summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-02-23 15:34:11 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-03-04 11:18:30 +0200
commitcf23d7740f54b8c53409e70eea244d984a27e537 (patch)
tree5b271f50c2a77822c8aee5cb05520f9ddbe5073a
parent7b6a8e42b5428038614faa2f44fc252f4bfd5f0a (diff)
Add elfutils to source tree and integrate build system
We only import the relevant parts of elfutils, leaving out the original build system, support for bzip2 and lzma compression, source code of the elfutils command line utilities, tests, and libcpu. Change-Id: I7c15cff880a7ab6d84e272c8b18f854f97539a1f Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
-rw-r--r--3rdparty/elfutils/AUTHORS4
-rw-r--r--3rdparty/elfutils/COPYING674
-rw-r--r--3rdparty/elfutils/COPYING-GPLV2339
-rw-r--r--3rdparty/elfutils/COPYING-LGPLV3165
-rw-r--r--3rdparty/elfutils/THANKS6
-rw-r--r--3rdparty/elfutils/backends/aarch64/aarch64.pro15
-rw-r--r--3rdparty/elfutils/backends/aarch64_cfi.c82
-rw-r--r--3rdparty/elfutils/backends/aarch64_corenote.c163
-rw-r--r--3rdparty/elfutils/backends/aarch64_init.c69
-rw-r--r--3rdparty/elfutils/backends/aarch64_initreg.c92
-rw-r--r--3rdparty/elfutils/backends/aarch64_regs.c102
-rw-r--r--3rdparty/elfutils/backends/aarch64_reloc.def157
-rw-r--r--3rdparty/elfutils/backends/aarch64_retval.c376
-rw-r--r--3rdparty/elfutils/backends/aarch64_symbol.c87
-rw-r--r--3rdparty/elfutils/backends/alpha/alpha.pro14
-rw-r--r--3rdparty/elfutils/backends/alpha_auxv.c49
-rw-r--r--3rdparty/elfutils/backends/alpha_corenote.c70
-rw-r--r--3rdparty/elfutils/backends/alpha_init.c70
-rw-r--r--3rdparty/elfutils/backends/alpha_regs.c164
-rw-r--r--3rdparty/elfutils/backends/alpha_reloc.def63
-rw-r--r--3rdparty/elfutils/backends/alpha_retval.c150
-rw-r--r--3rdparty/elfutils/backends/alpha_symbol.c156
-rw-r--r--3rdparty/elfutils/backends/arm/arm.pro17
-rw-r--r--3rdparty/elfutils/backends/arm_attrs.c245
-rw-r--r--3rdparty/elfutils/backends/arm_auxv.c49
-rw-r--r--3rdparty/elfutils/backends/arm_cfi.c90
-rw-r--r--3rdparty/elfutils/backends/arm_corenote.c94
-rw-r--r--3rdparty/elfutils/backends/arm_init.c76
-rw-r--r--3rdparty/elfutils/backends/arm_initreg.c92
-rw-r--r--3rdparty/elfutils/backends/arm_regs.c120
-rw-r--r--3rdparty/elfutils/backends/arm_reloc.def157
-rw-r--r--3rdparty/elfutils/backends/arm_retval.c127
-rw-r--r--3rdparty/elfutils/backends/arm_symbol.c131
-rw-r--r--3rdparty/elfutils/backends/backends.pri10
-rw-r--r--3rdparty/elfutils/backends/backends.pro3
-rw-r--r--3rdparty/elfutils/backends/common-reloc.c146
-rw-r--r--3rdparty/elfutils/backends/i386/i386.pro17
-rw-r--r--3rdparty/elfutils/backends/i386_auxv.c52
-rw-r--r--3rdparty/elfutils/backends/i386_cfi.c68
-rw-r--r--3rdparty/elfutils/backends/i386_corenote.c138
-rw-r--r--3rdparty/elfutils/backends/i386_init.c71
-rw-r--r--3rdparty/elfutils/backends/i386_initreg.c79
-rw-r--r--3rdparty/elfutils/backends/i386_regs.c152
-rw-r--r--3rdparty/elfutils/backends/i386_reloc.def70
-rw-r--r--3rdparty/elfutils/backends/i386_retval.c141
-rw-r--r--3rdparty/elfutils/backends/i386_symbol.c75
-rw-r--r--3rdparty/elfutils/backends/i386_syscall.c50
-rw-r--r--3rdparty/elfutils/backends/ia64/ia64.pro12
-rw-r--r--3rdparty/elfutils/backends/ia64_init.c67
-rw-r--r--3rdparty/elfutils/backends/ia64_regs.c273
-rw-r--r--3rdparty/elfutils/backends/ia64_reloc.def113
-rw-r--r--3rdparty/elfutils/backends/ia64_retval.c363
-rw-r--r--3rdparty/elfutils/backends/ia64_symbol.c157
-rw-r--r--3rdparty/elfutils/backends/libebl_CPU.h76
-rw-r--r--3rdparty/elfutils/backends/linux-core-note.c299
-rw-r--r--3rdparty/elfutils/backends/ppc/ppc.pro18
-rw-r--r--3rdparty/elfutils/backends/ppc64/ppc64.pro13
-rw-r--r--3rdparty/elfutils/backends/ppc64_corenote.c2
-rw-r--r--3rdparty/elfutils/backends/ppc64_init.c109
-rw-r--r--3rdparty/elfutils/backends/ppc64_reloc.def161
-rw-r--r--3rdparty/elfutils/backends/ppc64_resolve_sym.c63
-rw-r--r--3rdparty/elfutils/backends/ppc64_retval.c195
-rw-r--r--3rdparty/elfutils/backends/ppc64_symbol.c130
-rw-r--r--3rdparty/elfutils/backends/ppc_attrs.c89
-rw-r--r--3rdparty/elfutils/backends/ppc_auxv.c55
-rw-r--r--3rdparty/elfutils/backends/ppc_cfi.c77
-rw-r--r--3rdparty/elfutils/backends/ppc_corenote.c134
-rw-r--r--3rdparty/elfutils/backends/ppc_init.c74
-rw-r--r--3rdparty/elfutils/backends/ppc_initreg.c114
-rw-r--r--3rdparty/elfutils/backends/ppc_regs.c200
-rw-r--r--3rdparty/elfutils/backends/ppc_reloc.def137
-rw-r--r--3rdparty/elfutils/backends/ppc_retval.c191
-rw-r--r--3rdparty/elfutils/backends/ppc_symbol.c165
-rw-r--r--3rdparty/elfutils/backends/ppc_syscall.c53
-rw-r--r--3rdparty/elfutils/backends/s390/s390.pro17
-rw-r--r--3rdparty/elfutils/backends/s390_cfi.c65
-rw-r--r--3rdparty/elfutils/backends/s390_corenote.c189
-rw-r--r--3rdparty/elfutils/backends/s390_init.c80
-rw-r--r--3rdparty/elfutils/backends/s390_initreg.c95
-rw-r--r--3rdparty/elfutils/backends/s390_regs.c146
-rw-r--r--3rdparty/elfutils/backends/s390_reloc.def91
-rw-r--r--3rdparty/elfutils/backends/s390_retval.c144
-rw-r--r--3rdparty/elfutils/backends/s390_symbol.c56
-rw-r--r--3rdparty/elfutils/backends/s390_unwind.c139
-rw-r--r--3rdparty/elfutils/backends/s390x_corenote.c2
-rw-r--r--3rdparty/elfutils/backends/sh/sh.pro13
-rw-r--r--3rdparty/elfutils/backends/sh_corenote.c88
-rw-r--r--3rdparty/elfutils/backends/sh_init.c64
-rw-r--r--3rdparty/elfutils/backends/sh_regs.c191
-rw-r--r--3rdparty/elfutils/backends/sh_reloc.def67
-rw-r--r--3rdparty/elfutils/backends/sh_retval.c131
-rw-r--r--3rdparty/elfutils/backends/sh_symbol.c94
-rw-r--r--3rdparty/elfutils/backends/sparc/sparc.pro15
-rw-r--r--3rdparty/elfutils/backends/sparc64/sparc64.pro5
-rw-r--r--3rdparty/elfutils/backends/sparc64_corenote.c2
-rw-r--r--3rdparty/elfutils/backends/sparc_auxv.c46
-rw-r--r--3rdparty/elfutils/backends/sparc_corenote.c112
-rw-r--r--3rdparty/elfutils/backends/sparc_init.c76
-rw-r--r--3rdparty/elfutils/backends/sparc_regs.c111
-rw-r--r--3rdparty/elfutils/backends/sparc_reloc.def121
-rw-r--r--3rdparty/elfutils/backends/sparc_retval.c159
-rw-r--r--3rdparty/elfutils/backends/sparc_symbol.c148
-rw-r--r--3rdparty/elfutils/backends/tilegx/tilegx.pro13
-rw-r--r--3rdparty/elfutils/backends/tilegx_corenote.c64
-rw-r--r--3rdparty/elfutils/backends/tilegx_init.c60
-rw-r--r--3rdparty/elfutils/backends/tilegx_regs.c129
-rw-r--r--3rdparty/elfutils/backends/tilegx_reloc.def120
-rw-r--r--3rdparty/elfutils/backends/tilegx_retval.c154
-rw-r--r--3rdparty/elfutils/backends/tilegx_symbol.c57
-rw-r--r--3rdparty/elfutils/backends/x86_64/x86_64.pro17
-rw-r--r--3rdparty/elfutils/backends/x86_64_cfi.c63
-rw-r--r--3rdparty/elfutils/backends/x86_64_corenote.c112
-rw-r--r--3rdparty/elfutils/backends/x86_64_init.c68
-rw-r--r--3rdparty/elfutils/backends/x86_64_initreg.c73
-rw-r--r--3rdparty/elfutils/backends/x86_64_regs.c185
-rw-r--r--3rdparty/elfutils/backends/x86_64_reloc.def63
-rw-r--r--3rdparty/elfutils/backends/x86_64_retval.c194
-rw-r--r--3rdparty/elfutils/backends/x86_64_symbol.c60
-rw-r--r--3rdparty/elfutils/backends/x86_64_syscall.c50
-rw-r--r--3rdparty/elfutils/backends/x86_corenote.c51
-rw-r--r--3rdparty/elfutils/config.h106
-rw-r--r--3rdparty/elfutils/elfutils.pri10
-rw-r--r--3rdparty/elfutils/elfutils.pro24
-rw-r--r--3rdparty/elfutils/lib/color.c230
-rw-r--r--3rdparty/elfutils/lib/crc32.c98
-rw-r--r--3rdparty/elfutils/lib/crc32_file.c91
-rw-r--r--3rdparty/elfutils/lib/dynamicsizehash.c332
-rw-r--r--3rdparty/elfutils/lib/dynamicsizehash.h127
-rw-r--r--3rdparty/elfutils/lib/eu-config.h189
-rw-r--r--3rdparty/elfutils/lib/fixedsizehash.h267
-rw-r--r--3rdparty/elfutils/lib/lib.pro17
-rw-r--r--3rdparty/elfutils/lib/libheaders.pri11
-rw-r--r--3rdparty/elfutils/lib/list.h100
-rw-r--r--3rdparty/elfutils/lib/md5.c454
-rw-r--r--3rdparty/elfutils/lib/md5.h110
-rw-r--r--3rdparty/elfutils/lib/next_prime.c66
-rw-r--r--3rdparty/elfutils/lib/sha1.c391
-rw-r--r--3rdparty/elfutils/lib/sha1.h93
-rw-r--r--3rdparty/elfutils/lib/system.h185
-rw-r--r--3rdparty/elfutils/lib/xmalloc.c84
-rw-r--r--3rdparty/elfutils/lib/xstrdup.c43
-rw-r--r--3rdparty/elfutils/lib/xstrndup.c47
-rw-r--r--3rdparty/elfutils/libasm/asm_abort.c61
-rw-r--r--3rdparty/elfutils/libasm/asm_addint16.c32
-rw-r--r--3rdparty/elfutils/libasm/asm_addint32.c32
-rw-r--r--3rdparty/elfutils/libasm/asm_addint64.c32
-rw-r--r--3rdparty/elfutils/libasm/asm_addint8.c123
-rw-r--r--3rdparty/elfutils/libasm/asm_addsleb128.c99
-rw-r--r--3rdparty/elfutils/libasm/asm_addstrz.c128
-rw-r--r--3rdparty/elfutils/libasm/asm_adduint16.c32
-rw-r--r--3rdparty/elfutils/libasm/asm_adduint32.c32
-rw-r--r--3rdparty/elfutils/libasm/asm_adduint64.c32
-rw-r--r--3rdparty/elfutils/libasm/asm_adduint8.c56
-rw-r--r--3rdparty/elfutils/libasm/asm_adduleb128.c95
-rw-r--r--3rdparty/elfutils/libasm/asm_align.c179
-rw-r--r--3rdparty/elfutils/libasm/asm_begin.c184
-rw-r--r--3rdparty/elfutils/libasm/asm_end.c613
-rw-r--r--3rdparty/elfutils/libasm/asm_error.c96
-rw-r--r--3rdparty/elfutils/libasm/asm_fill.c77
-rw-r--r--3rdparty/elfutils/libasm/asm_getelf.c44
-rw-r--r--3rdparty/elfutils/libasm/asm_newabssym.c136
-rw-r--r--3rdparty/elfutils/libasm/asm_newcomsym.c117
-rw-r--r--3rdparty/elfutils/libasm/asm_newscn.c215
-rw-r--r--3rdparty/elfutils/libasm/asm_newscn_ingrp.c81
-rw-r--r--3rdparty/elfutils/libasm/asm_newscngrp.c105
-rw-r--r--3rdparty/elfutils/libasm/asm_newsubscn.c99
-rw-r--r--3rdparty/elfutils/libasm/asm_newsym.c138
-rw-r--r--3rdparty/elfutils/libasm/asm_scngrp_newsignature.c48
-rw-r--r--3rdparty/elfutils/libasm/asmheaders.pri6
-rw-r--r--3rdparty/elfutils/libasm/disasm_begin.c64
-rw-r--r--3rdparty/elfutils/libasm/disasm_cb.c179
-rw-r--r--3rdparty/elfutils/libasm/disasm_end.c45
-rw-r--r--3rdparty/elfutils/libasm/disasm_str.c72
-rw-r--r--3rdparty/elfutils/libasm/libasm.h202
-rw-r--r--3rdparty/elfutils/libasm/libasm.pro40
-rw-r--r--3rdparty/elfutils/libasm/libasmP.h307
-rw-r--r--3rdparty/elfutils/libasm/symbolhash.c54
-rw-r--r--3rdparty/elfutils/libasm/symbolhash.h40
-rw-r--r--3rdparty/elfutils/libdw/cfi.c504
-rw-r--r--3rdparty/elfutils/libdw/cfi.h235
-rw-r--r--3rdparty/elfutils/libdw/cie.c196
-rw-r--r--3rdparty/elfutils/libdw/dwarf.h798
-rw-r--r--3rdparty/elfutils/libdw/dwarf_abbrev_hash.c45
-rw-r--r--3rdparty/elfutils/libdw/dwarf_abbrev_hash.h39
-rw-r--r--3rdparty/elfutils/libdw/dwarf_abbrevhaschildren.c44
-rw-r--r--3rdparty/elfutils/libdw/dwarf_addrdie.c54
-rw-r--r--3rdparty/elfutils/libdw/dwarf_aggregate_size.c244
-rw-r--r--3rdparty/elfutils/libdw/dwarf_arrayorder.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_attr.c55
-rw-r--r--3rdparty/elfutils/libdw/dwarf_attr_integrate.c60
-rw-r--r--3rdparty/elfutils/libdw/dwarf_begin.c101
-rw-r--r--3rdparty/elfutils/libdw/dwarf_begin_elf.c395
-rw-r--r--3rdparty/elfutils/libdw/dwarf_bitoffset.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_bitsize.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_bytesize.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_cfi_addrframe.c57
-rw-r--r--3rdparty/elfutils/libdw/dwarf_cfi_end.c49
-rw-r--r--3rdparty/elfutils/libdw/dwarf_child.c176
-rw-r--r--3rdparty/elfutils/libdw/dwarf_cu_die.c68
-rw-r--r--3rdparty/elfutils/libdw/dwarf_cu_getdwarf.c47
-rw-r--r--3rdparty/elfutils/libdw/dwarf_cuoffset.c45
-rw-r--r--3rdparty/elfutils/libdw/dwarf_decl_column.c44
-rw-r--r--3rdparty/elfutils/libdw/dwarf_decl_file.c89
-rw-r--r--3rdparty/elfutils/libdw/dwarf_decl_line.c70
-rw-r--r--3rdparty/elfutils/libdw/dwarf_diecu.c55
-rw-r--r--3rdparty/elfutils/libdw/dwarf_diename.c48
-rw-r--r--3rdparty/elfutils/libdw/dwarf_dieoffset.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_end.c129
-rw-r--r--3rdparty/elfutils/libdw/dwarf_entry_breakpoints.c157
-rw-r--r--3rdparty/elfutils/libdw/dwarf_entrypc.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_error.c122
-rw-r--r--3rdparty/elfutils/libdw/dwarf_filesrc.c51
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formaddr.c59
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formblock.c95
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formflag.c61
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formref.c113
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formref_die.c121
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formsdata.c98
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formstring.c76
-rw-r--r--3rdparty/elfutils/libdw/dwarf_formudata.c233
-rw-r--r--3rdparty/elfutils/libdw/dwarf_frame_cfa.c80
-rw-r--r--3rdparty/elfutils/libdw/dwarf_frame_info.c53
-rw-r--r--3rdparty/elfutils/libdw/dwarf_frame_register.c123
-rw-r--r--3rdparty/elfutils/libdw/dwarf_func_inline.c101
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getabbrev.c165
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getabbrevattr.c80
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getabbrevcode.c44
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getabbrevtag.c44
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getalt.c42
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getarange_addr.c62
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getarangeinfo.c53
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getaranges.c265
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getattrcnt.c48
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getattrs.c120
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getcfi.c73
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getcfi_elf.c320
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getelf.c48
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getfuncs.c118
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getlocation.c853
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getlocation_attr.c122
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getlocation_die.c78
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getlocation_implicit_pointer.c79
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getmacros.c548
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getpubnames.c245
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getscopes.c201
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getscopes_die.c74
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getscopevar.c154
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getsrc_die.c78
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getsrc_file.c178
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getsrcdirs.c48
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getsrcfiles.c76
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getsrclines.c881
-rw-r--r--3rdparty/elfutils/libdw/dwarf_getstring.c66
-rw-r--r--3rdparty/elfutils/libdw/dwarf_hasattr.c85
-rw-r--r--3rdparty/elfutils/libdw/dwarf_hasattr_integrate.c59
-rw-r--r--3rdparty/elfutils/libdw/dwarf_haschildren.c52
-rw-r--r--3rdparty/elfutils/libdw/dwarf_hasform.c47
-rw-r--r--3rdparty/elfutils/libdw/dwarf_haspc.c54
-rw-r--r--3rdparty/elfutils/libdw/dwarf_highpc.c68
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineaddr.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_linebeginstatement.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineblock.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_linecol.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_linediscriminator.c45
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineendsequence.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineepiloguebegin.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineisa.c45
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineno.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineop_index.c45
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lineprologueend.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_linesrc.c56
-rw-r--r--3rdparty/elfutils/libdw/dwarf_lowpc.c49
-rw-r--r--3rdparty/elfutils/libdw/dwarf_macro_getparamcnt.c43
-rw-r--r--3rdparty/elfutils/libdw/dwarf_macro_getsrcfiles.c88
-rw-r--r--3rdparty/elfutils/libdw/dwarf_macro_opcode.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_macro_param.c46
-rw-r--r--3rdparty/elfutils/libdw/dwarf_macro_param1.c48
-rw-r--r--3rdparty/elfutils/libdw/dwarf_macro_param2.c55
-rw-r--r--3rdparty/elfutils/libdw/dwarf_next_cfi.c246
-rw-r--r--3rdparty/elfutils/libdw/dwarf_nextcu.c199
-rw-r--r--3rdparty/elfutils/libdw/dwarf_offabbrev.c51
-rw-r--r--3rdparty/elfutils/libdw/dwarf_offdie.c90
-rw-r--r--3rdparty/elfutils/libdw/dwarf_onearange.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_onesrcline.c50
-rw-r--r--3rdparty/elfutils/libdw/dwarf_peel_type.c74
-rw-r--r--3rdparty/elfutils/libdw/dwarf_ranges.c190
-rw-r--r--3rdparty/elfutils/libdw/dwarf_setalt.c40
-rw-r--r--3rdparty/elfutils/libdw/dwarf_siblingof.c136
-rw-r--r--3rdparty/elfutils/libdw/dwarf_sig8_hash.c41
-rw-r--r--3rdparty/elfutils/libdw/dwarf_sig8_hash.h38
-rw-r--r--3rdparty/elfutils/libdw/dwarf_srclang.c51
-rw-r--r--3rdparty/elfutils/libdw/dwarf_tag.c95
-rw-r--r--3rdparty/elfutils/libdw/dwarf_whatattr.c43
-rw-r--r--3rdparty/elfutils/libdw/dwarf_whatform.c43
-rw-r--r--3rdparty/elfutils/libdw/dwheaders.pri12
-rw-r--r--3rdparty/elfutils/libdw/encoded-value.h197
-rw-r--r--3rdparty/elfutils/libdw/fde.c297
-rw-r--r--3rdparty/elfutils/libdw/frame-cache.c66
-rw-r--r--3rdparty/elfutils/libdw/known-dwarf.h629
-rw-r--r--3rdparty/elfutils/libdw/libdw.h1026
-rw-r--r--3rdparty/elfutils/libdw/libdw.pro127
-rw-r--r--3rdparty/elfutils/libdw/libdwP.h802
-rw-r--r--3rdparty/elfutils/libdw/libdw_alloc.c78
-rw-r--r--3rdparty/elfutils/libdw/libdw_findcu.c172
-rw-r--r--3rdparty/elfutils/libdw/libdw_form.c132
-rw-r--r--3rdparty/elfutils/libdw/libdw_visit_scopes.c147
-rw-r--r--3rdparty/elfutils/libdw/memory-access.h272
-rw-r--r--3rdparty/elfutils/libdwelf/dwelf_dwarf_gnu_debugaltlink.c62
-rw-r--r--3rdparty/elfutils/libdwelf/dwelf_elf_gnu_build_id.c147
-rw-r--r--3rdparty/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c99
-rw-r--r--3rdparty/elfutils/libdwelf/dwelfheaders.pri5
-rw-r--r--3rdparty/elfutils/libdwelf/libdwelf.h72
-rw-r--r--3rdparty/elfutils/libdwelf/libdwelf.pro14
-rw-r--r--3rdparty/elfutils/libdwelf/libdwelfP.h42
-rw-r--r--3rdparty/elfutils/libdwfl/argp-std.c364
-rw-r--r--3rdparty/elfutils/libdwfl/core-file.c589
-rw-r--r--3rdparty/elfutils/libdwfl/cu.c312
-rw-r--r--3rdparty/elfutils/libdwfl/derelocate.c401
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_addrdie.c36
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_addrdwarf.c37
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_addrmodule.c38
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_begin.c51
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c128
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_build_id_find_elf.c174
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_cumodule.c36
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_dwarf_line.c43
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_end.c54
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_error.c159
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_frame.c474
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_frame_pc.c64
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_frame_regs.c57
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_getdwarf.c59
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_getmodules.c92
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_getsrc.c36
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_getsrclines.c48
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_line_comp_dir.c43
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_linecu.c41
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_lineinfo.c55
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_linemodule.c38
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module.c222
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_addrdie.c45
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_addrname.c38
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_addrsym.c289
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_build_id.c117
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_dwarf_cfi.c71
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_eh_cfi.c57
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_getdwarf.c1358
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_getelf.c67
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_getsrc.c81
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_getsrc_file.c167
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_getsym.c216
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_info.c61
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_nextcu.c44
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_register_names.c79
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_report_build_id.c80
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_module_return_value_location.c64
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_nextcu.c82
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_onesrcline.c56
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_report_elf.c338
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_segment_report_module.c922
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_validate_address.c61
-rw-r--r--3rdparty/elfutils/libdwfl/dwfl_version.c36
-rw-r--r--3rdparty/elfutils/libdwfl/dwflheaders.pri5
-rw-r--r--3rdparty/elfutils/libdwfl/elf-from-memory.c370
-rw-r--r--3rdparty/elfutils/libdwfl/find-debuginfo.c351
-rw-r--r--3rdparty/elfutils/libdwfl/frame_unwind.c725
-rw-r--r--3rdparty/elfutils/libdwfl/gzip.c295
-rw-r--r--3rdparty/elfutils/libdwfl/image-header.c101
-rw-r--r--3rdparty/elfutils/libdwfl/libdwfl.h812
-rw-r--r--3rdparty/elfutils/libdwfl/libdwfl.pro76
-rw-r--r--3rdparty/elfutils/libdwfl/libdwflP.h760
-rw-r--r--3rdparty/elfutils/libdwfl/libdwfl_crc32.c35
-rw-r--r--3rdparty/elfutils/libdwfl/libdwfl_crc32_file.c36
-rw-r--r--3rdparty/elfutils/libdwfl/lines.c52
-rw-r--r--3rdparty/elfutils/libdwfl/link_map.c1021
-rw-r--r--3rdparty/elfutils/libdwfl/linux-core-attach.c427
-rw-r--r--3rdparty/elfutils/libdwfl/linux-kernel-modules.c928
-rw-r--r--3rdparty/elfutils/libdwfl/linux-pid-attach.c475
-rw-r--r--3rdparty/elfutils/libdwfl/linux-proc-maps.c422
-rw-r--r--3rdparty/elfutils/libdwfl/offline.c311
-rw-r--r--3rdparty/elfutils/libdwfl/open.c182
-rw-r--r--3rdparty/elfutils/libdwfl/relocate.c683
-rw-r--r--3rdparty/elfutils/libdwfl/segment.c332
-rw-r--r--3rdparty/elfutils/libebl/ebl-hooks.h195
-rw-r--r--3rdparty/elfutils/libebl/ebl_check_special_section.c44
-rw-r--r--3rdparty/elfutils/libebl/ebl_check_special_symbol.c49
-rw-r--r--3rdparty/elfutils/libebl/ebl_syscall_abi.c45
-rw-r--r--3rdparty/elfutils/libebl/eblabicfi.c42
-rw-r--r--3rdparty/elfutils/libebl/eblauxvinfo.c103
-rw-r--r--3rdparty/elfutils/libebl/eblbackendname.c43
-rw-r--r--3rdparty/elfutils/libebl/eblbsspltp.c42
-rw-r--r--3rdparty/elfutils/libebl/eblcheckobjattr.c60
-rw-r--r--3rdparty/elfutils/libebl/eblcheckreloctargettype.c46
-rw-r--r--3rdparty/elfutils/libebl/eblclosebackend.c54
-rw-r--r--3rdparty/elfutils/libebl/eblcopyrelocp.c43
-rw-r--r--3rdparty/elfutils/libebl/eblcorenote.c86
-rw-r--r--3rdparty/elfutils/libebl/eblcorenotetypename.c109
-rw-r--r--3rdparty/elfutils/libebl/ebldebugscnp.c44
-rw-r--r--3rdparty/elfutils/libebl/ebldwarftoregno.c41
-rw-r--r--3rdparty/elfutils/libebl/ebldynamictagcheck.c56
-rw-r--r--3rdparty/elfutils/libebl/ebldynamictagname.c113
-rw-r--r--3rdparty/elfutils/libebl/eblelfclass.c42
-rw-r--r--3rdparty/elfutils/libebl/eblelfdata.c42
-rw-r--r--3rdparty/elfutils/libebl/eblelfmachine.c42
-rw-r--r--3rdparty/elfutils/libebl/eblgotpcreloccheck.c44
-rw-r--r--3rdparty/elfutils/libebl/eblgstrtab.c365
-rw-r--r--3rdparty/elfutils/libebl/eblheaders.pri10
-rw-r--r--3rdparty/elfutils/libebl/eblinitreg.c58
-rw-r--r--3rdparty/elfutils/libebl/eblmachineflagcheck.c43
-rw-r--r--3rdparty/elfutils/libebl/eblmachineflagname.c91
-rw-r--r--3rdparty/elfutils/libebl/eblmachinesectionflagcheck.c42
-rw-r--r--3rdparty/elfutils/libebl/eblnonerelocp.c43
-rw-r--r--3rdparty/elfutils/libebl/eblnormalizepc.c40
-rw-r--r--3rdparty/elfutils/libebl/eblobjecttypename.c63
-rw-r--r--3rdparty/elfutils/libebl/eblobjnote.c220
-rw-r--r--3rdparty/elfutils/libebl/eblobjnotetypename.c80
-rw-r--r--3rdparty/elfutils/libebl/eblopenbackend.c763
-rw-r--r--3rdparty/elfutils/libebl/eblosabiname.c84
-rw-r--r--3rdparty/elfutils/libebl/eblreginfo.c50
-rw-r--r--3rdparty/elfutils/libebl/eblrelativerelocp.c43
-rw-r--r--3rdparty/elfutils/libebl/eblrelocsimpletype.c42
-rw-r--r--3rdparty/elfutils/libebl/eblreloctypecheck.c43
-rw-r--r--3rdparty/elfutils/libebl/eblreloctypename.c53
-rw-r--r--3rdparty/elfutils/libebl/eblrelocvaliduse.c43
-rw-r--r--3rdparty/elfutils/libebl/eblresolvesym.c43
-rw-r--r--3rdparty/elfutils/libebl/eblretval.c44
-rw-r--r--3rdparty/elfutils/libebl/eblsectionname.c96
-rw-r--r--3rdparty/elfutils/libebl/eblsectionstripp.c67
-rw-r--r--3rdparty/elfutils/libebl/eblsectiontypename.c127
-rw-r--r--3rdparty/elfutils/libebl/eblsegmenttypename.c90
-rw-r--r--3rdparty/elfutils/libebl/eblshflagscombine.c44
-rw-r--r--3rdparty/elfutils/libebl/eblstother.c43
-rw-r--r--3rdparty/elfutils/libebl/eblstrtab.c358
-rw-r--r--3rdparty/elfutils/libebl/eblsymbolbindingname.c78
-rw-r--r--3rdparty/elfutils/libebl/eblsymboltypename.c84
-rw-r--r--3rdparty/elfutils/libebl/eblsysvhashentrysize.c42
-rw-r--r--3rdparty/elfutils/libebl/eblunwind.c43
-rw-r--r--3rdparty/elfutils/libebl/eblwstrtab.c359
-rw-r--r--3rdparty/elfutils/libebl/libebl.h466
-rw-r--r--3rdparty/elfutils/libebl/libebl.pro61
-rw-r--r--3rdparty/elfutils/libebl/libeblP.h97
-rw-r--r--3rdparty/elfutils/libelf/abstract.h312
-rw-r--r--3rdparty/elfutils/libelf/common.h163
-rw-r--r--3rdparty/elfutils/libelf/dl-hash.h82
-rw-r--r--3rdparty/elfutils/libelf/elf-knowledge.h104
-rw-r--r--3rdparty/elfutils/libelf/elf.h3363
-rw-r--r--3rdparty/elfutils/libelf/elf32/elf32.pro21
-rw-r--r--3rdparty/elfutils/libelf/elf32_checksum.c169
-rw-r--r--3rdparty/elfutils/libelf/elf32_fsize.c71
-rw-r--r--3rdparty/elfutils/libelf/elf32_getehdr.c99
-rw-r--r--3rdparty/elfutils/libelf/elf32_getphdr.c257
-rw-r--r--3rdparty/elfutils/libelf/elf32_getshdr.c287
-rw-r--r--3rdparty/elfutils/libelf/elf32_newehdr.c92
-rw-r--r--3rdparty/elfutils/libelf/elf32_newphdr.c182
-rw-r--r--3rdparty/elfutils/libelf/elf32_offscn.c101
-rw-r--r--3rdparty/elfutils/libelf/elf32_updatefile.c808
-rw-r--r--3rdparty/elfutils/libelf/elf32_updatenull.c417
-rw-r--r--3rdparty/elfutils/libelf/elf32_xlatetof.c123
-rw-r--r--3rdparty/elfutils/libelf/elf32_xlatetom.c128
-rw-r--r--3rdparty/elfutils/libelf/elf64/elf64.pro20
-rw-r--r--3rdparty/elfutils/libelf/elf64_checksum.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_fsize.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_getehdr.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_getphdr.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_getshdr.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_newehdr.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_newphdr.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_offscn.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_updatefile.c30
-rw-r--r--3rdparty/elfutils/libelf/elf64_updatenull.c30
-rw-r--r--3rdparty/elfutils/libelf/elf64_xlatetof.c31
-rw-r--r--3rdparty/elfutils/libelf/elf64_xlatetom.c31
-rw-r--r--3rdparty/elfutils/libelf/elf_begin.c1135
-rw-r--r--3rdparty/elfutils/libelf/elf_clone.c81
-rw-r--r--3rdparty/elfutils/libelf/elf_cntl.c83
-rw-r--r--3rdparty/elfutils/libelf/elf_end.c232
-rw-r--r--3rdparty/elfutils/libelf/elf_error.c309
-rw-r--r--3rdparty/elfutils/libelf/elf_fill.c47
-rw-r--r--3rdparty/elfutils/libelf/elf_flagdata.c71
-rw-r--r--3rdparty/elfutils/libelf/elf_flagehdr.c68
-rw-r--r--3rdparty/elfutils/libelf/elf_flagelf.c70
-rw-r--r--3rdparty/elfutils/libelf/elf_flagphdr.c68
-rw-r--r--3rdparty/elfutils/libelf/elf_flagscn.c68
-rw-r--r--3rdparty/elfutils/libelf/elf_flagshdr.c68
-rw-r--r--3rdparty/elfutils/libelf/elf_getarhdr.c74
-rw-r--r--3rdparty/elfutils/libelf/elf_getaroff.c54
-rw-r--r--3rdparty/elfutils/libelf/elf_getarsym.c309
-rw-r--r--3rdparty/elfutils/libelf/elf_getbase.c45
-rw-r--r--3rdparty/elfutils/libelf/elf_getdata.c487
-rw-r--r--3rdparty/elfutils/libelf/elf_getdata_rawchunk.c177
-rw-r--r--3rdparty/elfutils/libelf/elf_getident.c63
-rw-r--r--3rdparty/elfutils/libelf/elf_getphdrnum.c136
-rw-r--r--3rdparty/elfutils/libelf/elf_getscn.c89
-rw-r--r--3rdparty/elfutils/libelf/elf_getshdrnum.c90
-rw-r--r--3rdparty/elfutils/libelf/elf_getshdrstrndx.c229
-rw-r--r--3rdparty/elfutils/libelf/elf_gnu_hash.c47
-rw-r--r--3rdparty/elfutils/libelf/elf_hash.c45
-rw-r--r--3rdparty/elfutils/libelf/elf_kind.c45
-rw-r--r--3rdparty/elfutils/libelf/elf_memory.c52
-rw-r--r--3rdparty/elfutils/libelf/elf_ndxscn.c48
-rw-r--r--3rdparty/elfutils/libelf/elf_newdata.c109
-rw-r--r--3rdparty/elfutils/libelf/elf_newscn.c163
-rw-r--r--3rdparty/elfutils/libelf/elf_next.c73
-rw-r--r--3rdparty/elfutils/libelf/elf_nextscn.c89
-rw-r--r--3rdparty/elfutils/libelf/elf_rand.c65
-rw-r--r--3rdparty/elfutils/libelf/elf_rawdata.c78
-rw-r--r--3rdparty/elfutils/libelf/elf_rawfile.c69
-rw-r--r--3rdparty/elfutils/libelf/elf_readall.c152
-rw-r--r--3rdparty/elfutils/libelf/elf_scnshndx.c50
-rw-r--r--3rdparty/elfutils/libelf/elf_strptr.c161
-rw-r--r--3rdparty/elfutils/libelf/elf_update.c199
-rw-r--r--3rdparty/elfutils/libelf/elf_version.c70
-rw-r--r--3rdparty/elfutils/libelf/elfheaders.pri17
-rw-r--r--3rdparty/elfutils/libelf/exttypes.h102
-rw-r--r--3rdparty/elfutils/libelf/gelf.h332
-rw-r--r--3rdparty/elfutils/libelf/gelf_checksum.c49
-rw-r--r--3rdparty/elfutils/libelf/gelf_fsize.c111
-rw-r--r--3rdparty/elfutils/libelf/gelf_getauxv.c110
-rw-r--r--3rdparty/elfutils/libelf/gelf_getclass.c45
-rw-r--r--3rdparty/elfutils/libelf/gelf_getdyn.c111
-rw-r--r--3rdparty/elfutils/libelf/gelf_getehdr.c111
-rw-r--r--3rdparty/elfutils/libelf/gelf_getlib.c80
-rw-r--r--3rdparty/elfutils/libelf/gelf_getmove.c82
-rw-r--r--3rdparty/elfutils/libelf/gelf_getnote.c104
-rw-r--r--3rdparty/elfutils/libelf/gelf_getphdr.c142
-rw-r--r--3rdparty/elfutils/libelf/gelf_getrel.c102
-rw-r--r--3rdparty/elfutils/libelf/gelf_getrela.c103
-rw-r--r--3rdparty/elfutils/libelf/gelf_getshdr.c105
-rw-r--r--3rdparty/elfutils/libelf/gelf_getsym.c117
-rw-r--r--3rdparty/elfutils/libelf/gelf_getsyminfo.c80
-rw-r--r--3rdparty/elfutils/libelf/gelf_getsymshndx.c140
-rw-r--r--3rdparty/elfutils/libelf/gelf_getverdaux.c82
-rw-r--r--3rdparty/elfutils/libelf/gelf_getverdef.c81
-rw-r--r--3rdparty/elfutils/libelf/gelf_getvernaux.c84
-rw-r--r--3rdparty/elfutils/libelf/gelf_getverneed.c84
-rw-r--r--3rdparty/elfutils/libelf/gelf_getversym.c89
-rw-r--r--3rdparty/elfutils/libelf/gelf_newehdr.c48
-rw-r--r--3rdparty/elfutils/libelf/gelf_newphdr.c48
-rw-r--r--3rdparty/elfutils/libelf/gelf_offscn.c57
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_auxv.c114
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_dyn.c110
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_ehdr.c118
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_lib.c78
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_move.c80
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_phdr.c143
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_rel.c108
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_rela.c111
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_shdr.c111
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_sym.c119
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_syminfo.c86
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_symshndx.c149
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_verdaux.c81
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_verdef.c81
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_vernaux.c81
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_verneed.c81
-rw-r--r--3rdparty/elfutils/libelf/gelf_update_versym.c80
-rw-r--r--3rdparty/elfutils/libelf/gelf_xlate.c214
-rw-r--r--3rdparty/elfutils/libelf/gelf_xlate.h56
-rw-r--r--3rdparty/elfutils/libelf/gelf_xlatetof.c53
-rw-r--r--3rdparty/elfutils/libelf/gelf_xlatetom.c53
-rw-r--r--3rdparty/elfutils/libelf/gnuhash_xlate.h74
-rw-r--r--3rdparty/elfutils/libelf/libelf.h396
-rw-r--r--3rdparty/elfutils/libelf/libelf.pro95
-rw-r--r--3rdparty/elfutils/libelf/libelfP.h594
-rw-r--r--3rdparty/elfutils/libelf/libelf_crc32.c35
-rw-r--r--3rdparty/elfutils/libelf/libelf_next_prime.c33
-rw-r--r--3rdparty/elfutils/libelf/nlist.c243
-rw-r--r--3rdparty/elfutils/libelf/nlist.h56
-rw-r--r--3rdparty/elfutils/libelf/note_xlate.h64
-rw-r--r--3rdparty/elfutils/libelf/version_xlate.h220
-rw-r--r--3rdparty/elfutils/version.h38
-rw-r--r--app/app.pro52
-rw-r--r--app/main.cpp (renamed from main.cpp)0
-rw-r--r--app/perfattributes.cpp (renamed from perfattributes.cpp)0
-rw-r--r--app/perfattributes.h (renamed from perfattributes.h)0
-rw-r--r--app/perfdata.cpp (renamed from perfdata.cpp)0
-rw-r--r--app/perfdata.h (renamed from perfdata.h)0
-rw-r--r--app/perffeatures.cpp (renamed from perffeatures.cpp)0
-rw-r--r--app/perffeatures.h (renamed from perffeatures.h)0
-rw-r--r--app/perffilesection.cpp (renamed from perffilesection.cpp)0
-rw-r--r--app/perffilesection.h (renamed from perffilesection.h)0
-rw-r--r--app/perfheader.cpp (renamed from perfheader.cpp)0
-rw-r--r--app/perfheader.h (renamed from perfheader.h)0
-rw-r--r--app/perfregisterinfo.cpp (renamed from perfregisterinfo.cpp)0
-rw-r--r--app/perfregisterinfo.h (renamed from perfregisterinfo.h)0
-rw-r--r--app/perfstdin.cpp (renamed from perfstdin.cpp)0
-rw-r--r--app/perfstdin.h (renamed from perfstdin.h)0
-rw-r--r--app/perfunwind.cpp (renamed from perfunwind.cpp)1
-rw-r--r--app/perfunwind.h (renamed from perfunwind.h)2
-rw-r--r--perfparser.pro39
590 files changed, 78876 insertions, 38 deletions
diff --git a/3rdparty/elfutils/AUTHORS b/3rdparty/elfutils/AUTHORS
new file mode 100644
index 0000000..ef3c543
--- /dev/null
+++ b/3rdparty/elfutils/AUTHORS
@@ -0,0 +1,4 @@
+For Now:
+Ulrich Drepper.
+Roland McGrath
+Petr Machata
diff --git a/3rdparty/elfutils/COPYING b/3rdparty/elfutils/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/3rdparty/elfutils/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+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:
+
+ <program> Copyright (C) <year> <name of author>
+ 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
+<http://www.gnu.org/licenses/>.
+
+ 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
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/3rdparty/elfutils/COPYING-GPLV2 b/3rdparty/elfutils/COPYING-GPLV2
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/3rdparty/elfutils/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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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/3rdparty/elfutils/COPYING-LGPLV3 b/3rdparty/elfutils/COPYING-LGPLV3
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/3rdparty/elfutils/COPYING-LGPLV3
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ 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/3rdparty/elfutils/THANKS b/3rdparty/elfutils/THANKS
new file mode 100644
index 0000000..887c067
--- /dev/null
+++ b/3rdparty/elfutils/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/3rdparty/elfutils/backends/aarch64/aarch64.pro b/3rdparty/elfutils/backends/aarch64/aarch64.pro
new file mode 100644
index 0000000..28a34f6
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64/aarch64.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_aarch64
+
+SOURCES += \
+ ../aarch64_cfi.c \
+ ../aarch64_corenote.c \
+ ../aarch64_init.c \
+ ../aarch64_initreg.c \
+ ../aarch64_regs.c \
+ ../aarch64_retval.c \
+ ../aarch64_symbol.c
+
+HEADERS += \
+ ../aarch64_reloc.def
diff --git a/3rdparty/elfutils/backends/aarch64_cfi.c b/3rdparty/elfutils/backends/aarch64_cfi.c
new file mode 100644
index 0000000..acbb9b6
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_cfi.c
@@ -0,0 +1,82 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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),
+
+ /* 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/3rdparty/elfutils/backends/aarch64_corenote.c b/3rdparty/elfutils/backends/aarch64_corenote.c
new file mode 100644
index 0000000..9b42485
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_corenote.c
@@ -0,0 +1,163 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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"
+ }
+ };
+
+#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)
+
+#include "linux-core-note.c"
diff --git a/3rdparty/elfutils/backends/aarch64_init.c b/3rdparty/elfutils/backends/aarch64_init.c
new file mode 100644
index 0000000..b0fd17a
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_init.c
@@ -0,0 +1,69 @@
+/* Initialization of AArch64 specific backend library.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+
+const char *
+aarch64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "AARCH64";
+ 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, 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);
+
+ return MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/aarch64_initreg.c b/3rdparty/elfutils/backends/aarch64_initreg.c
new file mode 100644
index 0000000..9706205
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <assert.h>
+#ifdef __aarch64__
+# include <linux/uio.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+/* 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)))
+{
+#ifndef __aarch64__
+ 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/3rdparty/elfutils/backends/aarch64_regs.c b/3rdparty/elfutils/backends/aarch64_regs.c
new file mode 100644
index 0000000..7a8a678
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_regs.c
@@ -0,0 +1,102 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <dwarf.h>
+#include <stdarg.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+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;
+
+ __attribute__ ((format (printf, 3, 4)))
+ ssize_t
+ regtype (const char *setname, int type, 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;
+ }
+
+ *prefix = "";
+ *bits = 64;
+
+ 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/3rdparty/elfutils/backends/aarch64_reloc.def b/3rdparty/elfutils/backends/aarch64_reloc.def
new file mode 100644
index 0000000..36d29e6
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_reloc.def
@@ -0,0 +1,157 @@
+/* List the relocation types for AArch64. -*- C -*-
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (ABS64, REL|EXEC|DYN)
+RELOC_TYPE (ABS32, REL|EXEC|DYN)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JUMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (TLS_DTPMOD64, EXEC|DYN)
+RELOC_TYPE (TLS_DTPREL64, EXEC|DYN)
+RELOC_TYPE (TLS_TPREL64, 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/3rdparty/elfutils/backends/aarch64_retval.c b/3rdparty/elfutils/backends/aarch64_retval.c
new file mode 100644
index 0000000..68de307
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ /* Fall through. */
+
+ 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: /* sigle */
+ 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/3rdparty/elfutils/backends/aarch64_symbol.c b/3rdparty/elfutils/backends/aarch64_symbol.c
new file mode 100644
index 0000000..3fdc9cf
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_symbol.c
@@ -0,0 +1,87 @@
+/* AArch64 specific symbolic name 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#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)
+{
+ 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 to
+ .got[0] even if there is a .got.plt section. */
+bool
+aarch64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym,
+ const char *name, const GElf_Shdr *destshdr)
+{
+ if (name != NULL
+ && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+ if (sname != NULL && 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, ehdr->e_shstrndx, shdr->sh_name);
+ if (sname != NULL && strcmp (sname, ".got") == 0)
+ return sym->st_value == shdr->sh_addr;
+ }
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/3rdparty/elfutils/backends/alpha/alpha.pro b/3rdparty/elfutils/backends/alpha/alpha.pro
new file mode 100644
index 0000000..0f72400
--- /dev/null
+++ b/3rdparty/elfutils/backends/alpha/alpha.pro
@@ -0,0 +1,14 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_alpha
+
+SOURCES += \
+ ../alpha_auxv.c \
+ ../alpha_corenote.c \
+ ../alpha_init.c \
+ ../alpha_regs.c \
+ ../alpha_retval.c \
+ ../alpha_symbol.c
+
+HEADERS += \
+ ../alpha_reloc.def
diff --git a/3rdparty/elfutils/backends/alpha_auxv.c b/3rdparty/elfutils/backends/alpha_auxv.c
new file mode 100644
index 0000000..83e7199
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/backends/alpha_corenote.c b/3rdparty/elfutils/backends/alpha_corenote.c
new file mode 100644
index 0000000..6190df3
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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/3rdparty/elfutils/backends/alpha_init.c b/3rdparty/elfutils/backends/alpha_init.c
new file mode 100644
index 0000000..a3307d8
--- /dev/null
+++ b/3rdparty/elfutils/backends/alpha_init.c
@@ -0,0 +1,70 @@
+/* Initialization of Alpha specific backend library.
+ Copyright (C) 2002-2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+
+const char *
+alpha_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Alpha";
+ 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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/alpha_regs.c b/3rdparty/elfutils/backends/alpha_regs.c
new file mode 100644
index 0000000..436af3b
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/alpha_reloc.def b/3rdparty/elfutils/backends/alpha_reloc.def
new file mode 100644
index 0000000..ed7e5c3
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+/* 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/3rdparty/elfutils/backends/alpha_retval.c b/3rdparty/elfutils/backends/alpha_retval.c
new file mode 100644
index 0000000..53dbfa4
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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;
+ }
+ }
+
+ /* Else fall through. */
+
+ 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/3rdparty/elfutils/backends/alpha_symbol.c b/3rdparty/elfutils/backends/alpha_symbol.c
new file mode 100644
index 0000000..657d9ee
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#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)
+{
+ 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)),
+ GElf_Ehdr *ehdr __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/3rdparty/elfutils/backends/arm/arm.pro b/3rdparty/elfutils/backends/arm/arm.pro
new file mode 100644
index 0000000..89aa3c8
--- /dev/null
+++ b/3rdparty/elfutils/backends/arm/arm.pro
@@ -0,0 +1,17 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_arm
+
+SOURCES += \
+ ../arm_attrs.c \
+ ../arm_auxv.c \
+ ../arm_cfi.c \
+ ../arm_corenote.c \
+ ../arm_init.c \
+ ../arm_initreg.c \
+ ../arm_regs.c \
+ ../arm_retval.c \
+ ../arm_symbol.c
+
+HEADERS += \
+ ../arm_reloc.def
diff --git a/3rdparty/elfutils/backends/arm_attrs.c b/3rdparty/elfutils/backends/arm_attrs.c
new file mode 100644
index 0000000..c858715
--- /dev/null
+++ b/3rdparty/elfutils/backends/arm_attrs.c
@@ -0,0 +1,245 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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, vendor, tag, value, tag_name, value_name)
+ Ebl *ebl __attribute__ ((unused));
+ const char *vendor;
+ int tag;
+ uint64_t value __attribute__ ((unused));
+ 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/3rdparty/elfutils/backends/arm_auxv.c b/3rdparty/elfutils/backends/arm_auxv.c
new file mode 100644
index 0000000..3282baf
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/backends/arm_cfi.c b/3rdparty/elfutils/backends/arm_cfi.c
new file mode 100644
index 0000000..971a1fc
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/arm_corenote.c b/3rdparty/elfutils/backends/arm_corenote.c
new file mode 100644
index 0000000..c5d8d88
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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/3rdparty/elfutils/backends/arm_init.c b/3rdparty/elfutils/backends/arm_init.c
new file mode 100644
index 0000000..3283c97
--- /dev/null
+++ b/3rdparty/elfutils/backends/arm_init.c
@@ -0,0 +1,76 @@
+/* Initialization of Arm specific backend library.
+ Copyright (C) 2002, 2005, 2009, 2013, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+
+const char *
+arm_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "ARM";
+ 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);
+
+ /* 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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/arm_initreg.c b/3rdparty/elfutils/backends/arm_initreg.c
new file mode 100644
index 0000000..a0a9be9
--- /dev/null
+++ b/3rdparty/elfutils/backends/arm_initreg.c
@@ -0,0 +1,92 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined __arm__
+# include <sys/types.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#ifdef __aarch64__
+# include <linux/uio.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+/* 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
+
+#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 __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/3rdparty/elfutils/backends/arm_regs.c b/3rdparty/elfutils/backends/arm_regs.c
new file mode 100644
index 0000000..21c5ad3
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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;
+ /* Fall through. */
+ 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/3rdparty/elfutils/backends/arm_reloc.def b/3rdparty/elfutils/backends/arm_reloc.def
new file mode 100644
index 0000000..4b7894b
--- /dev/null
+++ b/3rdparty/elfutils/backends/arm_reloc.def
@@ -0,0 +1,157 @@
+/* List the relocation types for arm. -*- C -*-
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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/3rdparty/elfutils/backends/arm_retval.c b/3rdparty/elfutils/backends/arm_retval.c
new file mode 100644
index 0000000..7aced74
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/arm_symbol.c b/3rdparty/elfutils/backends/arm_symbol.c
new file mode 100644
index 0000000..cd467ff
--- /dev/null
+++ b/3rdparty/elfutils/backends/arm_symbol.c
@@ -0,0 +1,131 @@
+/* Arm specific symbolic name handling.
+ Copyright (C) 2002-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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#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)
+{
+ 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;
+}
diff --git a/3rdparty/elfutils/backends/backends.pri b/3rdparty/elfutils/backends/backends.pri
new file mode 100644
index 0000000..2295037
--- /dev/null
+++ b/3rdparty/elfutils/backends/backends.pri
@@ -0,0 +1,10 @@
+include(../elfutils.pri)
+include(../libebl/eblheaders.pri)
+
+HEADERS += \
+ $$PWD/libebl_CPU.h \
+ $$PWD/linux-core-note.c \
+ $$PWD/x86_corenote.c \
+ $$PWD/common-reloc.c
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/backends/backends.pro b/3rdparty/elfutils/backends/backends.pro
new file mode 100644
index 0000000..0d71325
--- /dev/null
+++ b/3rdparty/elfutils/backends/backends.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+
+SUBDIRS = aarch64 alpha arm i386 ia64 ppc ppc64 s390 sh sparc tilegx x86_64
diff --git a/3rdparty/elfutils/backends/common-reloc.c b/3rdparty/elfutils/backends/common-reloc.c
new file mode 100644
index 0000000..2667ec4
--- /dev/null
+++ b/3rdparty/elfutils/backends/common-reloc.c
@@ -0,0 +1,146 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libebl_CPU.h"
+#include <assert.h>
+
+#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;
+#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)))
+{
+ 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)
+{
+ return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
+}
+
+bool
+EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
+{
+ uint8_t uses = EBLHOOK(reloc_valid)[reloc];
+
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ assert (ehdr != NULL);
+ uint8_t type = ehdr->e_type;
+
+ return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
+}
+
+
+bool
+EBLHOOK(copy_reloc_p) (int reloc)
+{
+ return reloc == R_TYPE (COPY);
+}
+
+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->copy_reloc_p = EBLHOOK(copy_reloc_p);
+ ebl->none_reloc_p = EBLHOOK(none_reloc_p);
+#ifndef NO_RELATIVE_RELOC
+ ebl->relative_reloc_p = EBLHOOK(relative_reloc_p);
+#endif
+}
diff --git a/3rdparty/elfutils/backends/i386/i386.pro b/3rdparty/elfutils/backends/i386/i386.pro
new file mode 100644
index 0000000..a731e04
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386/i386.pro
@@ -0,0 +1,17 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_i386
+
+SOURCES += \
+ ../i386_auxv.c \
+ ../i386_cfi.c \
+ ../i386_corenote.c \
+ ../i386_init.c \
+ ../i386_initreg.c \
+ ../i386_regs.c \
+ ../i386_retval.c \
+ ../i386_symbol.c \
+ ../i386_syscall.c
+
+HEADERS += \
+ ../i386_reloc.def
diff --git a/3rdparty/elfutils/backends/i386_auxv.c b/3rdparty/elfutils/backends/i386_auxv.c
new file mode 100644
index 0000000..dba63fe
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/backends/i386_cfi.c b/3rdparty/elfutils/backends/i386_cfi.c
new file mode 100644
index 0000000..31f85f7
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/i386_corenote.c b/3rdparty/elfutils/backends/i386_corenote.c
new file mode 100644
index 0000000..15cd66b
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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/3rdparty/elfutils/backends/i386_init.c b/3rdparty/elfutils/backends/i386_init.c
new file mode 100644
index 0000000..1e0b486
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386_init.c
@@ -0,0 +1,71 @@
+/* Initialization of i386 specific backend library.
+ Copyright (C) 2000-2009, 2013 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+const char *
+i386_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Intel 80386";
+ 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, syscall_abi);
+ 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);
+
+ return MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/i386_initreg.c b/3rdparty/elfutils/backends/i386_initreg.c
new file mode 100644
index 0000000..51fd9ea
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined __i386__ || defined __x86_64__
+# include <sys/types.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#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/3rdparty/elfutils/backends/i386_regs.c b/3rdparty/elfutils/backends/i386_regs.c
new file mode 100644
index 0000000..fb8ded3
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386_regs.c
@@ -0,0 +1,152 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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;
+ 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/3rdparty/elfutils/backends/i386_reloc.def b/3rdparty/elfutils/backends/i386_reloc.def
new file mode 100644
index 0000000..bd273b3
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386_reloc.def
@@ -0,0 +1,70 @@
+/* List the relocation types for i386. -*- C -*-
+ Copyright (C) 2000, 2001, 2002, 2003, 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 <http://www.gnu.org/licenses/>. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (COPY, EXEC)
+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)
diff --git a/3rdparty/elfutils/backends/i386_retval.c b/3rdparty/elfutils/backends/i386_retval.c
new file mode 100644
index 0000000..9da797d
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386_retval.c
@@ -0,0 +1,141 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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;
+
+ /* Else fall through. */
+ }
+
+ 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/3rdparty/elfutils/backends/i386_symbol.c b/3rdparty/elfutils/backends/i386_symbol.c
new file mode 100644
index 0000000..7dbf899
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386_symbol.c
@@ -0,0 +1,75 @@
+/* i386 specific symbolic name handling.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#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)
+{
+ 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/3rdparty/elfutils/backends/i386_syscall.c b/3rdparty/elfutils/backends/i386_syscall.c
new file mode 100644
index 0000000..535dcd8
--- /dev/null
+++ b/3rdparty/elfutils/backends/i386_syscall.c
@@ -0,0 +1,50 @@
+/* Linux/i386 system call ABI in DWARF register numbers.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+int
+i386_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+ int *sp, int *pc, int *callno, int args[6])
+{
+ *sp = 4; /* %esp */
+ *pc = 8; /* %eip */
+ *callno = 0; /* %eax */
+ args[0] = 3; /* %ebx */
+ args[1] = 1; /* %ecx */
+ args[2] = 2; /* %edx */
+ args[3] = 6; /* %esi */
+ args[4] = 7; /* %edi */
+ args[5] = 5; /* %ebp */
+ return 0;
+}
diff --git a/3rdparty/elfutils/backends/ia64/ia64.pro b/3rdparty/elfutils/backends/ia64/ia64.pro
new file mode 100644
index 0000000..383e869
--- /dev/null
+++ b/3rdparty/elfutils/backends/ia64/ia64.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_ia64
+
+SOURCES += \
+ ../ia64_init.c \
+ ../ia64_regs.c \
+ ../ia64_retval.c \
+ ../ia64_symbol.c
+
+HEADERS += \
+ ../ia64_reloc.def
diff --git a/3rdparty/elfutils/backends/ia64_init.c b/3rdparty/elfutils/backends/ia64_init.c
new file mode 100644
index 0000000..91da748
--- /dev/null
+++ b/3rdparty/elfutils/backends/ia64_init.c
@@ -0,0 +1,67 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+const char *
+ia64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Intel IA-64";
+ 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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/ia64_regs.c b/3rdparty/elfutils/backends/ia64_regs.c
new file mode 100644
index 0000000..a27fe63
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/ia64_reloc.def b/3rdparty/elfutils/backends/ia64_reloc.def
new file mode 100644
index 0000000..9e058c8
--- /dev/null
+++ b/3rdparty/elfutils/backends/ia64_reloc.def
@@ -0,0 +1,113 @@
+/* List the relocation types for ia64. -*- C -*-
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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/3rdparty/elfutils/backends/ia64_retval.c b/3rdparty/elfutils/backends/ia64_retval.c
new file mode 100644
index 0000000..b5928c5
--- /dev/null
+++ b/3rdparty/elfutils/backends/ia64_retval.c
@@ -0,0 +1,363 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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
+
+
+/* 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. */
+
+ inline int hfa (const Dwarf_Op *loc, int nregs)
+ {
+ if (fpregs_used == 0)
+ *locp = loc;
+ else if (*locp != loc)
+ return 9;
+ return fpregs_used + nregs;
+ }
+
+ 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;
+
+ 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);
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/ia64_symbol.c b/3rdparty/elfutils/backends/ia64_symbol.c
new file mode 100644
index 0000000..f928b0b
--- /dev/null
+++ b/3rdparty/elfutils/backends/ia64_symbol.c
@@ -0,0 +1,157 @@
+/* IA-64 specific symbolic name handling.
+ Copyright (C) 2002-2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <assert.h>
+
+#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)
+{
+ 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/3rdparty/elfutils/backends/libebl_CPU.h b/3rdparty/elfutils/backends/libebl_CPU.h
new file mode 100644
index 0000000..ef2b922
--- /dev/null
+++ b/3rdparty/elfutils/backends/libebl_CPU.h
@@ -0,0 +1,76 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBEBL_CPU_H
+#define _LIBEBL_CPU_H 1
+
+#include <dwarf.h>
+#include <libeblP.h>
+
+#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 const char *EBLHOOK(init) (Elf *elf, GElf_Half machine,
+ Ebl *eh, size_t ehlen);
+
+#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/3rdparty/elfutils/backends/linux-core-note.c b/3rdparty/elfutils/backends/linux-core-note.c
new file mode 100644
index 0000000..e3c0109
--- /dev/null
+++ b/3rdparty/elfutils/backends/linux-core-note.c
@@ -0,0 +1,299 @@
+/* Common core note type descriptions for Linux.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+
+/* 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 <linux/elfcore.h>. */
+
+#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
+#define ALIGN_INT 4
+#define TYPE_INT ELF_T_SWORD
+#ifndef ALIGN_PR_REG
+# define ALIGN_PR_REG ALIGN_ULONG
+#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 (ULONG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (ULONG)]);
+ }
+#ifdef ALIGN_PR_REG
+ __attribute__ ((aligned (ALIGN_PR_REG)))
+#endif
+ ;
+ FIELD (INT, pr_fpvalid);
+};
+
+#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 (UID_T, pr_uid);
+ FIELD (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, UID_T, uid, 'd'),
+ FIELD (identity, 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) (nhdr, name, regs_offset, nregloc, reglocs, nitems, items)
+ 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".
+ Fall through. */
+
+ 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/3rdparty/elfutils/backends/ppc/ppc.pro b/3rdparty/elfutils/backends/ppc/ppc.pro
new file mode 100644
index 0000000..cb202fd
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc/ppc.pro
@@ -0,0 +1,18 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_ppc
+
+SOURCES += \
+ ../ppc_attrs.c \
+ ../ppc_auxv.c \
+ ../ppc_cfi.c \
+ ../ppc_corenote.c \
+ ../ppc_init.c \
+ ../ppc_initreg.c \
+ ../ppc_regs.c \
+ ../ppc_retval.c \
+ ../ppc_symbol.c \
+ ../ppc_syscall.c
+
+HEADERS += \
+ ../ppc_reloc.def
diff --git a/3rdparty/elfutils/backends/ppc64/ppc64.pro b/3rdparty/elfutils/backends/ppc64/ppc64.pro
new file mode 100644
index 0000000..32078a9
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc64/ppc64.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_ppc64
+
+SOURCES += \
+ ../ppc64_corenote.c \
+ ../ppc64_init.c \
+ ../ppc64_resolve_sym.c \
+ ../ppc64_retval.c \
+ ../ppc64_symbol.c
+
+HEADERS += \
+ ../ppc64_reloc.def
diff --git a/3rdparty/elfutils/backends/ppc64_corenote.c b/3rdparty/elfutils/backends/ppc64_corenote.c
new file mode 100644
index 0000000..9d6a6a4
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc64_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "ppc_corenote.c"
diff --git a/3rdparty/elfutils/backends/ppc64_init.c b/3rdparty/elfutils/backends/ppc64_init.c
new file mode 100644
index 0000000..56e1828
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc64_init.c
@@ -0,0 +1,109 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#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"
+
+
+const char *
+ppc64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "PowerPC 64-bit";
+ 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, syscall_abi);
+ HOOK (eh, core_note);
+ HOOK (eh, auxv_info);
+ 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, 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);
+ if (ehdr != NULL && ehdr->e_type != ET_REL)
+ {
+ /* 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, ehdr->e_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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/ppc64_reloc.def b/3rdparty/elfutils/backends/ppc64_reloc.def
new file mode 100644
index 0000000..3a693cf
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc64_reloc.def
@@ -0,0 +1,161 @@
+/* List the relocation types for ppc64. -*- 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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/3rdparty/elfutils/backends/ppc64_resolve_sym.c b/3rdparty/elfutils/backends/ppc64_resolve_sym.c
new file mode 100644
index 0000000..03f6558
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/backends/ppc64_retval.c b/3rdparty/elfutils/backends/ppc64_retval.c
new file mode 100644
index 0000000..a251983
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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;
+ }
+
+ /* Else fall through. */
+ 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;
+ }
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/ppc64_symbol.c b/3rdparty/elfutils/backends/ppc64_symbol.c
new file mode 100644
index 0000000..0feddce
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc64_symbol.c
@@ -0,0 +1,130 @@
+/* PPC64 specific symbolic name handling.
+ Copyright (C) 2004, 2005, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#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)
+{
+ 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, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym __attribute__ ((unused)),
+ const char *name __attribute__ ((unused)),
+ const GElf_Shdr *destshdr)
+{
+ const char *sname = elf_strptr (elf, ehdr->e_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/3rdparty/elfutils/backends/ppc_attrs.c b/3rdparty/elfutils/backends/ppc_attrs.c
new file mode 100644
index 0000000..ebeafe5
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_attrs.c
@@ -0,0 +1,89 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+bool
+ppc_check_object_attribute (ebl, vendor, tag, value, tag_name, value_name)
+ 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",
+ };
+ 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/3rdparty/elfutils/backends/ppc_auxv.c b/3rdparty/elfutils/backends/ppc_auxv.c
new file mode 100644
index 0000000..a27a1da
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/backends/ppc_cfi.c b/3rdparty/elfutils/backends/ppc_cfi.c
new file mode 100644
index 0000000..55169ae
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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 adress,
+ 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/3rdparty/elfutils/backends/ppc_corenote.c b/3rdparty/elfutils/backends/ppc_corenote.c
new file mode 100644
index 0000000..9ac8871
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_corenote.c
@@ -0,0 +1,134 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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 }
+ };
+
+#define EXTRA_NOTES \
+ EXTRA_REGSET (NT_PPC_VMX, 34 * 16, altivec_regs) \
+ EXTRA_REGSET (NT_PPC_SPE, 35 * 4, spe_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/3rdparty/elfutils/backends/ppc_init.c b/3rdparty/elfutils/backends/ppc_init.c
new file mode 100644
index 0000000..ad92765
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_init.c
@@ -0,0 +1,74 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+
+const char *
+ppc_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "PowerPC";
+ ppc_init_reloc (eh);
+ HOOK (eh, reloc_simple_type);
+ 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, syscall_abi);
+ 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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/ppc_initreg.c b/3rdparty/elfutils/backends/ppc_initreg.c
new file mode 100644
index 0000000..64f5379
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_initreg.c
@@ -0,0 +1,114 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <stdlib.h>
+#ifdef __powerpc__
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#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)))
+{
+#ifndef __powerpc__
+ 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;
+ }
+ const size_t 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/3rdparty/elfutils/backends/ppc_regs.c b/3rdparty/elfutils/backends/ppc_regs.c
new file mode 100644
index 0000000..4b92a9a
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_regs.c
@@ -0,0 +1,200 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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;
+
+ case 102 ... 107:
+ name[0] = 's';
+ name[1] = 'p';
+ name[2] = 'r';
+ name[3] = (regno - 100) + '0';
+ namelen = 4;
+ break;
+
+ case 110 ... 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/3rdparty/elfutils/backends/ppc_reloc.def b/3rdparty/elfutils/backends/ppc_reloc.def
new file mode 100644
index 0000000..dc963a0
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_reloc.def
@@ -0,0 +1,137 @@
+/* List the relocation types for ppc. -*- 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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/3rdparty/elfutils/backends/ppc_retval.c b/3rdparty/elfutils/backends/ppc_retval.c
new file mode 100644
index 0000000..b14a99f
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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;
+ }
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/ppc_symbol.c b/3rdparty/elfutils/backends/ppc_symbol.c
new file mode 100644
index 0000000..c17ab37
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_symbol.c
@@ -0,0 +1,165 @@
+/* PPC specific symbolic name handling.
+ Copyright (C) 2004, 2005, 2007, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#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)
+{
+ 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;
+ }
+}
+
+
+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";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+bool
+ppc_dynamic_tag_check (int64_t tag)
+{
+ return tag == DT_PPC_GOT;
+}
+
+
+/* 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)
+ 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, GElf_Ehdr *ehdr, 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;
+ }
+
+ const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+ if (sname == NULL)
+ return false;
+
+ if (strcmp (name, "_SDA_BASE_") == 0)
+ return (strcmp (sname, ".sdata") == 0
+ && sym->st_value == destshdr->sh_addr + 0x8000
+ && 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/3rdparty/elfutils/backends/ppc_syscall.c b/3rdparty/elfutils/backends/ppc_syscall.c
new file mode 100644
index 0000000..b1b9c52
--- /dev/null
+++ b/3rdparty/elfutils/backends/ppc_syscall.c
@@ -0,0 +1,53 @@
+/* Linux/PPC system call ABI in DWARF register numbers.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+int
+ppc_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+ int *sp, int *pc, int *callno, int args[6])
+{
+ *sp = 1;
+ *pc = -1;
+ *callno = 0;
+ args[0] = 3;
+ args[1] = 4;
+ args[2] = 5;
+ args[3] = 6;
+ args[4] = 7;
+ args[5] = 8;
+ return 0;
+}
+
+__typeof (ppc_syscall_abi)
+ppc64_syscall_abi __attribute__ ((alias ("ppc_syscall_abi")));
diff --git a/3rdparty/elfutils/backends/s390/s390.pro b/3rdparty/elfutils/backends/s390/s390.pro
new file mode 100644
index 0000000..73d3bec
--- /dev/null
+++ b/3rdparty/elfutils/backends/s390/s390.pro
@@ -0,0 +1,17 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_s390
+
+SOURCES += \
+ ../s390_cfi.c \
+ ../s390_corenote.c \
+ ../s390_init.c \
+ ../s390_initreg.c \
+ ../s390_regs.c \
+ ../s390_retval.c \
+ ../s390_symbol.c \
+ ../s390_unwind.c \
+ ../s390x_corenote.c
+
+HEADERS += \
+ ../s390_reloc.def
diff --git a/3rdparty/elfutils/backends/s390_cfi.c b/3rdparty/elfutils/backends/s390_cfi.c
new file mode 100644
index 0000000..cb49486
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/s390_corenote.c b/3rdparty/elfutils/backends/s390_corenote.c
new file mode 100644
index 0000000..7ca3516
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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/3rdparty/elfutils/backends/s390_init.c b/3rdparty/elfutils/backends/s390_init.c
new file mode 100644
index 0000000..26b20b4
--- /dev/null
+++ b/3rdparty/elfutils/backends/s390_init.c
@@ -0,0 +1,80 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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;
+
+
+const char *
+s390_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "IBM S/390";
+ s390_init_reloc (eh);
+ HOOK (eh, reloc_simple_type);
+ 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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/s390_initreg.c b/3rdparty/elfutils/backends/s390_initreg.c
new file mode 100644
index 0000000..b4c4b67
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <assert.h>
+#ifdef __s390__
+# include <sys/user.h>
+# include <asm/ptrace.h>
+# include <sys/ptrace.h>
+#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)))
+{
+#ifndef __s390__
+ 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/3rdparty/elfutils/backends/s390_regs.c b/3rdparty/elfutils/backends/s390_regs.c
new file mode 100644
index 0000000..ba6178a
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/s390_reloc.def b/3rdparty/elfutils/backends/s390_reloc.def
new file mode 100644
index 0000000..b4686a3
--- /dev/null
+++ b/3rdparty/elfutils/backends/s390_reloc.def
@@ -0,0 +1,91 @@
+/* List the relocation types for s390. -*- C -*-
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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/3rdparty/elfutils/backends/s390_retval.c b/3rdparty/elfutils/backends/s390_retval.c
new file mode 100644
index 0000000..a927d46
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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;
+ }
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/s390_symbol.c b/3rdparty/elfutils/backends/s390_symbol.c
new file mode 100644
index 0000000..a0a4faf
--- /dev/null
+++ b/3rdparty/elfutils/backends/s390_symbol.c
@@ -0,0 +1,56 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#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)
+{
+ 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;
+ }
+}
diff --git a/3rdparty/elfutils/backends/s390_unwind.c b/3rdparty/elfutils/backends/s390_unwind.c
new file mode 100644
index 0000000..752bc28
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+#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/3rdparty/elfutils/backends/s390x_corenote.c b/3rdparty/elfutils/backends/s390x_corenote.c
new file mode 100644
index 0000000..427bf7d
--- /dev/null
+++ b/3rdparty/elfutils/backends/s390x_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "s390_corenote.c"
diff --git a/3rdparty/elfutils/backends/sh/sh.pro b/3rdparty/elfutils/backends/sh/sh.pro
new file mode 100644
index 0000000..af42586
--- /dev/null
+++ b/3rdparty/elfutils/backends/sh/sh.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_sh
+
+SOURCES += \
+ ../sh_corenote.c \
+ ../sh_init.c \
+ ../sh_regs.c \
+ ../sh_retval.c \
+ ../sh_symbol.c
+
+HEADERS += \
+ ../sh_reloc.def
diff --git a/3rdparty/elfutils/backends/sh_corenote.c b/3rdparty/elfutils/backends/sh_corenote.c
new file mode 100644
index 0000000..9268f56
--- /dev/null
+++ b/3rdparty/elfutils/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 <matt@console-pimps.org>.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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/3rdparty/elfutils/backends/sh_init.c b/3rdparty/elfutils/backends/sh_init.c
new file mode 100644
index 0000000..90ddcb2
--- /dev/null
+++ b/3rdparty/elfutils/backends/sh_init.c
@@ -0,0 +1,64 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+
+const char *
+sh_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Hitachi SH";
+ 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 MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/sh_regs.c b/3rdparty/elfutils/backends/sh_regs.c
new file mode 100644
index 0000000..d433236
--- /dev/null
+++ b/3rdparty/elfutils/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 <matt@console-pimps.org>.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <string.h>
+
+#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/3rdparty/elfutils/backends/sh_reloc.def b/3rdparty/elfutils/backends/sh_reloc.def
new file mode 100644
index 0000000..66a5a9d
--- /dev/null
+++ b/3rdparty/elfutils/backends/sh_reloc.def
@@ -0,0 +1,67 @@
+/* List the relocation types for SH. -*- 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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/3rdparty/elfutils/backends/sh_retval.c b/3rdparty/elfutils/backends/sh_retval.c
new file mode 100644
index 0000000..d44f260
--- /dev/null
+++ b/3rdparty/elfutils/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 <matt@console-pimps.org>.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/sh_symbol.c b/3rdparty/elfutils/backends/sh_symbol.c
new file mode 100644
index 0000000..8101e96
--- /dev/null
+++ b/3rdparty/elfutils/backends/sh_symbol.c
@@ -0,0 +1,94 @@
+/* SH specific relocation handling.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#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)
+{
+ 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/3rdparty/elfutils/backends/sparc/sparc.pro b/3rdparty/elfutils/backends/sparc/sparc.pro
new file mode 100644
index 0000000..4ffe731
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc/sparc.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_sparc
+
+SOURCES += \
+ ../sparc_auxv.c \
+ ../sparc_corenote.c \
+ ../sparc_init.c \
+ ../sparc_regs.c \
+ ../sparc_retval.c \
+ ../sparc_symbol.c \
+ ../sparc64_corenote.c
+
+HEADERS += \
+ ../sparc_reloc.def
diff --git a/3rdparty/elfutils/backends/sparc64/sparc64.pro b/3rdparty/elfutils/backends/sparc64/sparc64.pro
new file mode 100644
index 0000000..ee9051b
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc64/sparc64.pro
@@ -0,0 +1,5 @@
+TEMPLATE = lib
+include(../backends.pri)
+
+SOURCES += \
+
diff --git a/3rdparty/elfutils/backends/sparc64_corenote.c b/3rdparty/elfutils/backends/sparc64_corenote.c
new file mode 100644
index 0000000..cef6431
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc64_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "sparc_corenote.c"
diff --git a/3rdparty/elfutils/backends/sparc_auxv.c b/3rdparty/elfutils/backends/sparc_auxv.c
new file mode 100644
index 0000000..2da349c
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/backends/sparc_corenote.c b/3rdparty/elfutils/backends/sparc_corenote.c
new file mode 100644
index 0000000..7912539
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc_corenote.c
@@ -0,0 +1,112 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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
+
+#include "linux-core-note.c"
diff --git a/3rdparty/elfutils/backends/sparc_init.c b/3rdparty/elfutils/backends/sparc_init.c
new file mode 100644
index 0000000..7d22998
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc_init.c
@@ -0,0 +1,76 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND sparc_
+#define RELOC_PREFIX R_SPARC_
+#include "libebl_CPU.h"
+
+/* 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;
+
+const char *
+sparc_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ if (machine == EM_SPARCV9)
+ eh->name = "SPARC v9";
+ else if (machine == EM_SPARC32PLUS)
+ eh->name = "SPARC v8+";
+ else
+ eh->name = "SPARC";
+ 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);
+
+ return MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/sparc_regs.c b/3rdparty/elfutils/backends/sparc_regs.c
new file mode 100644
index 0000000..f9709bb
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc_regs.c
@@ -0,0 +1,111 @@
+/* Register names and numbers for SPARC DWARF.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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->machine == EM_SPARC ? 0 : 16);
+ const int nspec = ebl->machine == EM_SPARC ? 8 : 6;
+
+ if (name == NULL)
+ return 32 + nfp + nspec;
+
+ if (regno < 0 || regno >= 32 + nfp + nspec || namelen < 6)
+ return -1;
+
+ *bits = ebl->machine == EM_SPARC ? 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->machine != EM_SPARC ? 0 : 4) + 1 - (unsigned int) regno <= 1)
+ *type = DW_ATE_address;
+ return stpncpy (name, names[ebl->machine != EM_SPARC][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/3rdparty/elfutils/backends/sparc_reloc.def b/3rdparty/elfutils/backends/sparc_reloc.def
new file mode 100644
index 0000000..c39b0fa
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc_reloc.def
@@ -0,0 +1,121 @@
+/* List the relocation types for sparc. -*- C -*-
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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, DYN)
+RELOC_TYPE (GOTDATA_OP_LOX10, DYN)
+RELOC_TYPE (GOTDATA_OP, DYN)
+RELOC_TYPE (H34, REL)
+RELOC_TYPE (SIZE32, REL)
+RELOC_TYPE (SIZE64, REL)
+RELOC_TYPE (GNU_VTINHERIT, REL)
+RELOC_TYPE (GNU_VTENTRY, REL)
+RELOC_TYPE (REV32, REL)
diff --git a/3rdparty/elfutils/backends/sparc_retval.c b/3rdparty/elfutils/backends/sparc_retval.c
new file mode 100644
index 0000000..e1b1775
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/sparc_symbol.c b/3rdparty/elfutils/backends/sparc_symbol.c
new file mode 100644
index 0000000..ec11dc9
--- /dev/null
+++ b/3rdparty/elfutils/backends/sparc_symbol.c
@@ -0,0 +1,148 @@
+/* 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 <jakub@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#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)
+{
+ 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/3rdparty/elfutils/backends/tilegx/tilegx.pro b/3rdparty/elfutils/backends/tilegx/tilegx.pro
new file mode 100644
index 0000000..ee751b5
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx/tilegx.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_tilegx
+
+SOURCES += \
+ ../tilegx_corenote.c \
+ ../tilegx_init.c \
+ ../tilegx_regs.c \
+ ../tilegx_retval.c \
+ ../tilegx_symbol.c
+
+HEADERS += \
+ ../tilegx_reloc.def
diff --git a/3rdparty/elfutils/backends/tilegx_corenote.c b/3rdparty/elfutils/backends/tilegx_corenote.c
new file mode 100644
index 0000000..be3e7db
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx_corenote.c
@@ -0,0 +1,64 @@
+/* TILE-Gx specific core note handling.
+ 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 <http://www.gnu.org/licenses/>. */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND tilegx_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+ {
+ { .offset = 0, .regno = 0, .count = 56, .bits = 64 }, /* r0-r55 */
+ { .offset = 56 * 8, .regno = 64, .count = 1, .bits = 64 } /* pc */
+ };
+#define PRSTATUS_REGS_SIZE (57 * 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/3rdparty/elfutils/backends/tilegx_init.c b/3rdparty/elfutils/backends/tilegx_init.c
new file mode 100644
index 0000000..858798b
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx_init.c
@@ -0,0 +1,60 @@
+/* Initialization of TILE-Gx specific backend library.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND tilegx_
+#define RELOC_PREFIX R_TILEGX_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on tilegx_reloc.def. */
+#include "common-reloc.c"
+
+const char *
+tilegx_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "TILE-Gx";
+ tilegx_init_reloc (eh);
+ HOOK (eh, reloc_simple_type);
+ HOOK (eh, return_value_location);
+ HOOK (eh, register_info);
+ HOOK (eh, core_note);
+
+ return MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/tilegx_regs.c b/3rdparty/elfutils/backends/tilegx_regs.c
new file mode 100644
index 0000000..b1e1743
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx_regs.c
@@ -0,0 +1,129 @@
+/* Register names and numbers for TILE-Gx DWARF.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND tilegx_
+#include "libebl_CPU.h"
+
+ssize_t
+tilegx_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 65;
+
+ if (regno < 0 || regno > 64 || namelen < 5)
+ return -1;
+
+ *prefix = "";
+ *setname = "integer";
+ *bits = 64;
+
+ switch (regno)
+ {
+ case 0 ... 9:
+ *type = DW_ATE_signed;
+ name[0] = 'r';
+ name[1] = regno + '0';
+ namelen = 2;
+ break;
+
+ case 10 ... 52:
+ *type = DW_ATE_signed;
+ name[0] = 'r';
+ name[1] = regno / 10 + '0';
+ name[2] = regno % 10 + '0';
+ namelen = 3;
+ break;
+
+ case 53:
+ *type = DW_ATE_address;
+ return stpcpy (name, "tp") + 1 - name;
+
+ case 54:
+ *type = DW_ATE_address;
+ return stpcpy (name, "sp") + 1 - name;
+
+ case 55:
+ *type = DW_ATE_address;
+ return stpcpy (name, "lr") + 1 - name;
+
+ case 56:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "sn") + 1 - name;
+
+ case 57:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "idn0") + 1 - name;
+
+ case 58:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "idn1") + 1 - name;
+
+ case 59:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "udn0") + 1 - name;
+
+ case 60:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "udn1") + 1 - name;
+
+ case 61:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "udn2") + 1 - name;
+
+ case 62:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "udn3") + 1 - name;
+
+ case 63:
+ *type = DW_ATE_unsigned;
+ return stpcpy (name, "zero") + 1 - name;
+
+ case 64:
+ *type = DW_ATE_address;
+ return stpcpy (name, "pc") + 1 - name;
+
+ /* Can't happen. */
+ default:
+ *setname = NULL;
+ return 0;
+ }
+
+ name[namelen++] = '\0';
+ return namelen;
+}
diff --git a/3rdparty/elfutils/backends/tilegx_reloc.def b/3rdparty/elfutils/backends/tilegx_reloc.def
new file mode 100644
index 0000000..9736286
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx_reloc.def
@@ -0,0 +1,120 @@
+/* List the relocation types for tilegx. -*- C -*-
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (64, REL|EXEC|DYN)
+RELOC_TYPE (32, REL|EXEC|DYN)
+RELOC_TYPE (16, REL|EXEC|DYN)
+RELOC_TYPE (8, REL|EXEC|DYN)
+RELOC_TYPE (64_PCREL, REL)
+RELOC_TYPE (32_PCREL, REL)
+RELOC_TYPE (16_PCREL, REL)
+RELOC_TYPE (8_PCREL, REL)
+RELOC_TYPE (HW0, REL)
+RELOC_TYPE (HW1, REL)
+RELOC_TYPE (HW2, REL)
+RELOC_TYPE (HW3, REL)
+RELOC_TYPE (HW0_LAST, REL)
+RELOC_TYPE (HW1_LAST, REL)
+RELOC_TYPE (HW2_LAST, REL)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (BROFF_X1, REL)
+RELOC_TYPE (JUMPOFF_X1, REL)
+RELOC_TYPE (JUMPOFF_X1_PLT, REL)
+RELOC_TYPE (IMM8_X0, REL)
+RELOC_TYPE (IMM8_Y0, REL)
+RELOC_TYPE (IMM8_X1, REL)
+RELOC_TYPE (IMM8_Y1, REL)
+RELOC_TYPE (DEST_IMM8_X1, REL)
+RELOC_TYPE (MT_IMM14_X1, REL)
+RELOC_TYPE (MF_IMM14_X1, REL)
+RELOC_TYPE (MMSTART_X0, REL)
+RELOC_TYPE (MMEND_X0, REL)
+RELOC_TYPE (SHAMT_X0, REL)
+RELOC_TYPE (SHAMT_X1, REL)
+RELOC_TYPE (SHAMT_Y0, REL)
+RELOC_TYPE (SHAMT_Y1, REL)
+RELOC_TYPE (IMM16_X0_HW0, REL)
+RELOC_TYPE (IMM16_X1_HW0, REL)
+RELOC_TYPE (IMM16_X0_HW1, REL)
+RELOC_TYPE (IMM16_X1_HW1, REL)
+RELOC_TYPE (IMM16_X0_HW2, REL)
+RELOC_TYPE (IMM16_X1_HW2, REL)
+RELOC_TYPE (IMM16_X0_HW3, REL)
+RELOC_TYPE (IMM16_X1_HW3, REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST, REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST, REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST, REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST, REL)
+RELOC_TYPE (IMM16_X0_HW2_LAST, REL)
+RELOC_TYPE (IMM16_X1_HW2_LAST, REL)
+RELOC_TYPE (IMM16_X0_HW0_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW0_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW1_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW1_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW2_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW2_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW3_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW3_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW2_LAST_PCREL, REL)
+RELOC_TYPE (IMM16_X1_HW2_LAST_PCREL, REL)
+RELOC_TYPE (IMM16_X0_HW0_GOT, REL)
+RELOC_TYPE (IMM16_X1_HW0_GOT, REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_GOT, REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_GOT, REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_GOT, REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_GOT, REL)
+RELOC_TYPE (IMM16_X0_HW0_TLS_GD, REL)
+RELOC_TYPE (IMM16_X1_HW0_TLS_GD, REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_TLS_GD, REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_TLS_GD, REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_TLS_GD, REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_TLS_GD, REL)
+RELOC_TYPE (IMM16_X0_HW0_TLS_IE, REL)
+RELOC_TYPE (IMM16_X1_HW0_TLS_IE, REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_TLS_IE, REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_TLS_IE, REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_TLS_IE, REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_TLS_IE, REL)
+RELOC_TYPE (TLS_DTPMOD64, EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF64, EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF64, EXEC|DYN)
+RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF32, EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF32, EXEC|DYN)
+RELOC_TYPE (GNU_VTINHERIT, REL)
+RELOC_TYPE (GNU_VTENTRY, REL)
diff --git a/3rdparty/elfutils/backends/tilegx_retval.c b/3rdparty/elfutils/backends/tilegx_retval.c
new file mode 100644
index 0000000..db81a20
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx_retval.c
@@ -0,0 +1,154 @@
+/* Function return value location for Linux/TILE-Gx ABI.
+ Copyright (C) 2012 Tilera Corporation
+ 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 <http://www.gnu.org/licenses/>. */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND tilegx_
+#include "libebl_CPU.h"
+
+
+/* r0. */
+static const Dwarf_Op loc_intreg[] =
+ {
+ { .atom = DW_OP_reg0 }
+ };
+#define nloc_intreg 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 r0. */
+static const Dwarf_Op loc_aggregate[] =
+ {
+ { .atom = DW_OP_breg0, .number = 0 }
+ };
+#define nloc_aggregate 1
+
+int
+tilegx_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);
+ }
+ /* Fall through. */
+
+ 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_Word encoding;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+ &attr_mem),
+ &encoding) != 0)
+ return -1;
+ }
+ }
+
+ /* Small enough structs are passed directly in registers R0 ... R7. */
+ if (size <= 8)
+ {
+ intreg:
+ *locp = loc_intreg;
+ return nloc_intreg;
+ }
+
+ /* Else fall through. */
+ 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:
+ case DW_TAG_string_type:
+ if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8)
+ {
+ if (tag == DW_TAG_array_type)
+ {
+ Dwarf_Attribute attr_mem, *attr;
+ /* Check if it's a character array. */
+ 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/3rdparty/elfutils/backends/tilegx_symbol.c b/3rdparty/elfutils/backends/tilegx_symbol.c
new file mode 100644
index 0000000..b653326
--- /dev/null
+++ b/3rdparty/elfutils/backends/tilegx_symbol.c
@@ -0,0 +1,57 @@
+/* TILEGX-specific symbolic name handling.
+ 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 <http://www.gnu.org/licenses/>. */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#define BACKEND tilegx_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types. */
+Elf_Type
+tilegx_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_TILEGX_64:
+ return ELF_T_SXWORD;
+ case R_TILEGX_32:
+ return ELF_T_SWORD;
+ case R_TILEGX_16:
+ return ELF_T_HALF;
+ case R_TILEGX_8:
+ return ELF_T_BYTE;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/3rdparty/elfutils/backends/x86_64/x86_64.pro b/3rdparty/elfutils/backends/x86_64/x86_64.pro
new file mode 100644
index 0000000..fa6060f
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64/x86_64.pro
@@ -0,0 +1,17 @@
+TEMPLATE = lib
+include(../backends.pri)
+TARGET = ../ebl_x86_64
+
+SOURCES += \
+ ../x86_64_cfi.c \
+ ../x86_64_corenote.c \
+ ../x86_64_init.c \
+ ../x86_64_initreg.c \
+ ../x86_64_regs.c \
+ ../x86_64_retval.c \
+ ../x86_64_symbol.c \
+ ../x86_64_syscall.c \
+ ../x86_corenote.c
+
+HEADERS += \
+ ../x86_64_reloc.def
diff --git a/3rdparty/elfutils/backends/x86_64_cfi.c b/3rdparty/elfutils/backends/x86_64_cfi.c
new file mode 100644
index 0000000..6db8ac4
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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/3rdparty/elfutils/backends/x86_64_corenote.c b/3rdparty/elfutils/backends/x86_64_corenote.c
new file mode 100644
index 0000000..f9d8db4
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64_corenote.c
@@ -0,0 +1,112 @@
+/* x86-64 specific core note handling.
+ Copyright (C) 2005, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND x86_64_
+#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)
+
+#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_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/3rdparty/elfutils/backends/x86_64_init.c b/3rdparty/elfutils/backends/x86_64_init.c
new file mode 100644
index 0000000..b885558
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64_init.c
@@ -0,0 +1,68 @@
+/* Initialization of x86-64 specific backend library.
+ Copyright (C) 2002-2009, 2013 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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"
+
+const char *
+x86_64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "AMD x86-64";
+ x86_64_init_reloc (eh);
+ HOOK (eh, reloc_simple_type);
+ HOOK (eh, core_note);
+ HOOK (eh, return_value_location);
+ HOOK (eh, register_info);
+ HOOK (eh, syscall_abi);
+ 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);
+
+ return MODVERSION;
+}
diff --git a/3rdparty/elfutils/backends/x86_64_initreg.c b/3rdparty/elfutils/backends/x86_64_initreg.c
new file mode 100644
index 0000000..db9216e
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#ifdef __x86_64__
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#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/3rdparty/elfutils/backends/x86_64_regs.c b/3rdparty/elfutils/backends/x86_64_regs.c
new file mode 100644
index 0000000..2172d9f
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64_regs.c
@@ -0,0 +1,185 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <string.h>
+
+#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;
+ 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/3rdparty/elfutils/backends/x86_64_reloc.def b/3rdparty/elfutils/backends/x86_64_reloc.def
new file mode 100644
index 0000000..8ed98f6
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64_reloc.def
@@ -0,0 +1,63 @@
+/* List the relocation types for x86-64. -*- C -*-
+ Copyright (C) 2000, 2001, 2002, 2003, 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
+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)
diff --git a/3rdparty/elfutils/backends/x86_64_retval.c b/3rdparty/elfutils/backends/x86_64_retval.c
new file mode 100644
index 0000000..b3799ae
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#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);
+ }
+ /* Fall through. */
+
+ 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/3rdparty/elfutils/backends/x86_64_symbol.c b/3rdparty/elfutils/backends/x86_64_symbol.c
new file mode 100644
index 0000000..1622461
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64_symbol.c
@@ -0,0 +1,60 @@
+/* x86_64 specific symbolic name handling.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+
+#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)
+{
+ 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;
+ }
+}
diff --git a/3rdparty/elfutils/backends/x86_64_syscall.c b/3rdparty/elfutils/backends/x86_64_syscall.c
new file mode 100644
index 0000000..0deb8ba
--- /dev/null
+++ b/3rdparty/elfutils/backends/x86_64_syscall.c
@@ -0,0 +1,50 @@
+/* Linux/x86-64 system call ABI in DWARF register numbers.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+int
+x86_64_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+ int *sp, int *pc, int *callno, int args[6])
+{
+ *sp = 7; /* %rsp */
+ *pc = 16; /* %rip */
+ *callno = 0; /* %rax */
+ args[0] = 5; /* %rdi */
+ args[1] = 4; /* %rsi */
+ args[2] = 1; /* %rdx */
+ args[3] = 10; /* %r10 */
+ args[4] = 8; /* %r8 */
+ args[5] = 9; /* %r9 */
+ return 0;
+}
diff --git a/3rdparty/elfutils/backends/x86_corenote.c b/3rdparty/elfutils/backends/x86_corenote.c
new file mode 100644
index 0000000..629462c
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/config.h b/3rdparty/elfutils/config.h
new file mode 100644
index 0000000..fbf5f8e
--- /dev/null
+++ b/3rdparty/elfutils/config.h
@@ -0,0 +1,106 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Should ar and ranlib use -D behavior by default? */
+#define DEFAULT_AR_DETERMINISTIC false
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if <sys/user.h> defines struct user_regs_struct */
+#define HAVE_SYS_USER_REGS 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* $libdir subdirectory containing libebl modules. */
+#define LIBEBL_SUBDIR "elfutils"
+
+/* Identifier for modules in the build. */
+#define MODVERSION "Build on zebra 2015-02-03T13:51:12+0100"
+
+/* Define to 32 or 64 if a specific implementation is wanted. */
+/* #undef NATIVE_ELF */
+
+/* Name of package */
+#define PACKAGE "elfutils"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://bugzilla.redhat.com/"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "elfutils"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "elfutils 0.161"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "elfutils"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.161"
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Support bzip2 decompression via -lbz2. */
+/* #undef USE_BZLIB */
+
+/* Defined if demangling is enabled */
+#define USE_DEMANGLE 1
+
+/* Defined if libraries should be thread-safe. */
+/* #undef USE_LOCKS */
+
+/* Support LZMA (xz) decompression via -llzma. */
+/* #undef USE_LZMA */
+
+/* Support gzip decompression via -lz. */
+#define USE_ZLIB 1
+
+/* Version number of package */
+#define VERSION "0.161"
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#define YYTEXT_POINTER 1
+
+/* 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 <eu-config.h>
diff --git a/3rdparty/elfutils/elfutils.pri b/3rdparty/elfutils/elfutils.pri
new file mode 100644
index 0000000..bdbf5db
--- /dev/null
+++ b/3rdparty/elfutils/elfutils.pri
@@ -0,0 +1,10 @@
+VERSION = 0.161
+QMAKE_CFLAGS += -std=gnu99
+DEFINES += HAVE_CONFIG_H _GNU_SOURCE
+
+HEADERS += \
+ $$PWD/version.h \
+ $$PWD/config.h
+
+INCLUDEPATH += $$PWD
+include(lib/libheaders.pri)
diff --git a/3rdparty/elfutils/elfutils.pro b/3rdparty/elfutils/elfutils.pro
new file mode 100644
index 0000000..78d3798
--- /dev/null
+++ b/3rdparty/elfutils/elfutils.pro
@@ -0,0 +1,24 @@
+TEMPLATE = subdirs
+
+# split out libelf's 32bit and 64bit specific parts as qmake will see the include directives in
+# the 64bit versions and then not compile the 32bit ones
+
+SUBDIRS = \
+ backends \
+ lib \
+ libasm \
+ libebl \
+ libelf \
+ libelf/elf32 \
+ libelf/elf64 \
+ libdw \
+ libdwelf \
+ libdwfl
+
+OTHER_FILES += \
+ COPYING \
+ COPYING-GPLV2 \
+ COPYING-LGPLV3 \
+ AUTHORS \
+ THANKS
+
diff --git a/3rdparty/elfutils/lib/color.c b/3rdparty/elfutils/lib/color.c
new file mode 100644
index 0000000..d1309ed
--- /dev/null
+++ b/3rdparty/elfutils/lib/color.c
@@ -0,0 +1,230 @@
+/* Handling of color output.
+ Copyright (C) 2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "system.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_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, dgettext ("elfutils", "\
+%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,
+ 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 (o1, operand2),
+ E (o1, operand3),
+ 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,
+ gettext ("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 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_operand3 = xstrdup ("\e[38;5;112m");
+ color_label = xstrdup ("\e[38;5;21m");
+ }
+#endif
+ }
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
diff --git a/3rdparty/elfutils/lib/crc32.c b/3rdparty/elfutils/lib/crc32.c
new file mode 100644
index 0000000..1a76b1b
--- /dev/null
+++ b/3rdparty/elfutils/lib/crc32.c
@@ -0,0 +1,98 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+#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/3rdparty/elfutils/lib/crc32_file.c b/3rdparty/elfutils/lib/crc32_file.c
new file mode 100644
index 0000000..c0b18e9
--- /dev/null
+++ b/3rdparty/elfutils/lib/crc32_file.c
@@ -0,0 +1,91 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.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_PAGE_SIZE);
+ 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/3rdparty/elfutils/lib/dynamicsizehash.c b/3rdparty/elfutils/lib/dynamicsizehash.c
new file mode 100644
index 0000000..1fdff1b
--- /dev/null
+++ b/3rdparty/elfutils/lib/dynamicsizehash.c
@@ -0,0 +1,332 @@
+/* Copyright (C) 2000-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <system.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
+ 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 (htab, hval, val)
+ 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) (htab, init_size)
+ 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) (htab)
+ NAME *htab;
+{
+ free (htab->table);
+ return 0;
+}
+
+
+int
+#define INSERT(name) _INSERT (name)
+#define _INSERT(name) \
+ name##_insert
+INSERT(NAME) (htab, hval, data)
+ 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) (htab, hval, data)
+ 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) (htab, hval, val)
+ 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) (htab, ptr)
+ 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/3rdparty/elfutils/lib/dynamicsizehash.h b/3rdparty/elfutils/lib/dynamicsizehash.h
new file mode 100644
index 0000000..ccd41d0
--- /dev/null
+++ b/3rdparty/elfutils/lib/dynamicsizehash.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 2000-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <stddef.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
+ */
+
+
+/* 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/3rdparty/elfutils/lib/eu-config.h b/3rdparty/elfutils/lib/eu-config.h
new file mode 100644
index 0000000..3afff26
--- /dev/null
+++ b/3rdparty/elfutils/lib/eu-config.h
@@ -0,0 +1,189 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef EU_CONFIG_H
+#define EU_CONFIG_H 1
+
+#ifdef USE_LOCKS
+# include <pthread.h>
+# include <assert.h>
+# 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 macro. */
+#define N_(Str) 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;
+
+#define attribute_hidden \
+ __attribute__ ((visibility ("hidden")))
+
+/* Define ALLOW_UNALIGNED if the architecture allows operations on
+ unaligned memory locations. */
+#if defined __i386__ || defined __x86_64__
+# 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) <lib##name.h>
+
+
+#ifdef SHARED
+# 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 SHARED"
+# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SHARED"
+#endif
+
+
+#endif /* eu-config.h */
diff --git a/3rdparty/elfutils/lib/fixedsizehash.h b/3rdparty/elfutils/lib/fixedsizehash.h
new file mode 100644
index 0000000..06ce6a2
--- /dev/null
+++ b/3rdparty/elfutils/lib/fixedsizehash.h
@@ -0,0 +1,267 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include <system.h>
+
+#define CONCAT(t1,t2) __CONCAT (t1,t2)
+
+/* 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/3rdparty/elfutils/lib/lib.pro b/3rdparty/elfutils/lib/lib.pro
new file mode 100644
index 0000000..f1663f8
--- /dev/null
+++ b/3rdparty/elfutils/lib/lib.pro
@@ -0,0 +1,17 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../eu
+
+include(../elfutils.pri)
+
+SOURCES += \
+ $$PWD/color.c \
+ $$PWD/crc32_file.c \
+ $$PWD/crc32.c \
+ $$PWD/md5.c \
+ $$PWD/next_prime.c \
+ $$PWD/sha1.c \
+ $$PWD/xmalloc.c \
+ $$PWD/xstrdup.c \
+ $$PWD/xstrndup.c
+
diff --git a/3rdparty/elfutils/lib/libheaders.pri b/3rdparty/elfutils/lib/libheaders.pri
new file mode 100644
index 0000000..66f022e
--- /dev/null
+++ b/3rdparty/elfutils/lib/libheaders.pri
@@ -0,0 +1,11 @@
+HEADERS += \
+ $$PWD/eu-config.h \
+ $$PWD/dynamicsizehash.h \
+ $$PWD/dynamicsizehash.c \
+ $$PWD/fixedsizehash.h \
+ $$PWD/list.h \
+ $$PWD/md5.h \
+ $$PWD/sha1.h \
+ $$PWD/system.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/lib/list.h b/3rdparty/elfutils/lib/list.h
new file mode 100644
index 0000000..fc5c73c
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/lib/md5.c b/3rdparty/elfutils/lib/md5.c
new file mode 100644
index 0000000..1c27549
--- /dev/null
+++ b/3rdparty/elfutils/lib/md5.c
@@ -0,0 +1,454 @@
+/* Functions to compute MD5 message digest of files or memory blocks.
+ according to the definition of MD5 in RFC 1321 from April 1992.
+ Copyright (C) 1995-2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1995.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "md5.h"
+#include "system.h"
+
+#define SWAP(n) LE32 (n)
+
+/* This array contains the bytes used to pad the buffer to the next
+ 64-byte boundary. (RFC 1321, 3.1: Step 1) */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
+
+
+/* Initialize structure containing state of computation.
+ (RFC 1321, 3.3: Step 3) */
+void
+md5_init_ctx (ctx)
+ struct md5_ctx *ctx;
+{
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->total[0] = ctx->total[1] = 0;
+ ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF. The result
+ must be in little endian byte order.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+void *
+md5_read_ctx (ctx, resbuf)
+ const struct md5_ctx *ctx;
+ void *resbuf;
+{
+ ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+ ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+ ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+ ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+ return resbuf;
+}
+
+static void
+le64_copy (char *dest, uint64_t x)
+{
+ for (size_t i = 0; i < 8; ++i)
+ {
+ dest[i] = (uint8_t) x;
+ x >>= 8;
+ }
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+ prolog according to the standard and write the result to RESBUF.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+void *
+md5_finish_ctx (ctx, resbuf)
+ struct md5_ctx *ctx;
+ void *resbuf;
+{
+ /* Take yet unprocessed bytes into account. */
+ md5_uint32 bytes = ctx->buflen;
+ size_t pad;
+
+ /* Now count remaining bytes. */
+ ctx->total[0] += bytes;
+ if (ctx->total[0] < bytes)
+ ++ctx->total[1];
+
+ pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+ memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+ /* Put the 64-bit file length in *bits* at the end of the buffer. */
+ const uint64_t bit_length = ((ctx->total[0] << 3)
+ + ((uint64_t) ((ctx->total[1] << 3) |
+ (ctx->total[0] >> 29)) << 32));
+ le64_copy (&ctx->buffer[bytes + pad], bit_length);
+
+ /* Process last bytes. */
+ md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+ return md5_read_ctx (ctx, resbuf);
+}
+
+
+#ifdef NEED_MD5_STREAM
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+int
+md5_stream (stream, resblock)
+ FILE *stream;
+ void *resblock;
+{
+ /* Important: BLOCKSIZE must be a multiple of 64. */
+#define BLOCKSIZE 4096
+ struct md5_ctx ctx;
+ char buffer[BLOCKSIZE + 72];
+ size_t sum;
+
+ /* Initialize the computation context. */
+ md5_init_ctx (&ctx);
+
+ /* Iterate over full file contents. */
+ while (1)
+ {
+ /* We read the file in blocks of BLOCKSIZE bytes. One call of the
+ computation function processes the whole buffer so that with the
+ next round of the loop another block can be read. */
+ size_t n;
+ sum = 0;
+
+ /* Read block. Take care for partial reads. */
+ do
+ {
+ n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+ sum += n;
+ }
+ while (sum < BLOCKSIZE && n != 0);
+ if (n == 0 && ferror (stream))
+ return 1;
+
+ /* If end of file is reached, end the loop. */
+ if (n == 0)
+ break;
+
+ /* Process buffer with BLOCKSIZE bytes. Note that
+ BLOCKSIZE % 64 == 0
+ */
+ md5_process_block (buffer, BLOCKSIZE, &ctx);
+ }
+
+ /* Add the last bytes if necessary. */
+ if (sum > 0)
+ md5_process_bytes (buffer, sum, &ctx);
+
+ /* Construct result in desired memory. */
+ md5_finish_ctx (&ctx, resblock);
+ return 0;
+}
+#endif
+
+
+#ifdef NEED_MD5_BUFFER
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
+ result is always in little endian byte order, so that a byte-wise
+ output yields to the wanted ASCII representation of the message
+ digest. */
+void *
+md5_buffer (buffer, len, resblock)
+ const char *buffer;
+ size_t len;
+ void *resblock;
+{
+ struct md5_ctx ctx;
+
+ /* Initialize the computation context. */
+ md5_init_ctx (&ctx);
+
+ /* Process whole buffer but last len % 64 bytes. */
+ md5_process_bytes (buffer, len, &ctx);
+
+ /* Put result in desired memory area. */
+ return md5_finish_ctx (&ctx, resblock);
+}
+#endif
+
+
+void
+md5_process_bytes (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct md5_ctx *ctx;
+{
+ /* When we already have some bits in our internal buffer concatenate
+ both inputs first. */
+ if (ctx->buflen != 0)
+ {
+ size_t left_over = ctx->buflen;
+ size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+ memcpy (&ctx->buffer[left_over], buffer, add);
+ ctx->buflen += add;
+
+ if (ctx->buflen > 64)
+ {
+ md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+
+ ctx->buflen &= 63;
+ /* The regions in the following copy operation cannot overlap. */
+ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+ ctx->buflen);
+ }
+
+ buffer = (const char *) buffer + add;
+ len -= add;
+ }
+
+ /* Process available complete blocks. */
+ if (len >= 64)
+ {
+#if !_STRING_ARCH_unaligned
+/* To check alignment gcc has an appropriate operator. Other
+ compilers don't. */
+# if __GNUC__ >= 2
+# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
+# else
+# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
+# endif
+ if (UNALIGNED_P (buffer))
+ while (len > 64)
+ {
+ md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+ buffer = (const char *) buffer + 64;
+ len -= 64;
+ }
+ else
+#endif
+ {
+ md5_process_block (buffer, len & ~63, ctx);
+ buffer = (const char *) buffer + (len & ~63);
+ len &= 63;
+ }
+ }
+
+ /* Move remaining bytes in internal buffer. */
+ if (len > 0)
+ {
+ size_t left_over = ctx->buflen;
+
+ memcpy (&ctx->buffer[left_over], buffer, len);
+ left_over += len;
+ if (left_over >= 64)
+ {
+ md5_process_block (ctx->buffer, 64, ctx);
+ left_over -= 64;
+ memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+ }
+ ctx->buflen = left_over;
+ }
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+ It is assumed that LEN % 64 == 0. */
+
+void
+md5_process_block (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct md5_ctx *ctx;
+{
+ md5_uint32 correct_words[16];
+ const md5_uint32 *words = buffer;
+ size_t nwords = len / sizeof (md5_uint32);
+ const md5_uint32 *endp = words + nwords;
+ md5_uint32 A = ctx->A;
+ md5_uint32 B = ctx->B;
+ md5_uint32 C = ctx->C;
+ md5_uint32 D = ctx->D;
+
+ /* First increment the byte count. RFC 1321 specifies the possible
+ length of the file up to 2^64 bits. Here we only compute the
+ number of bytes. Do a double word increment. */
+ ctx->total[0] += len;
+ if (ctx->total[0] < len)
+ ++ctx->total[1];
+
+ /* Process all bytes in the buffer with 64 bytes in each round of
+ the loop. */
+ while (words < endp)
+ {
+ md5_uint32 *cwp = correct_words;
+ md5_uint32 A_save = A;
+ md5_uint32 B_save = B;
+ md5_uint32 C_save = C;
+ md5_uint32 D_save = D;
+
+ /* First round: using the given function, the context and a constant
+ the next context is computed. Because the algorithms processing
+ unit is a 32-bit word and it is determined to work on words in
+ little endian byte order we perhaps have to change the byte order
+ before the computation. To reduce the work for the next steps
+ we store the swapped words in the array CORRECT_WORDS. */
+
+#define OP(a, b, c, d, s, T) \
+ do \
+ { \
+ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
+ ++words; \
+ CYCLIC (a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* It is unfortunate that C does not provide an operator for
+ cyclic rotation. Hope the C compiler is smart enough. */
+#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
+
+ /* Before we start, one word to the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+ /* For the second to fourth round we have the possibly swapped words
+ in CORRECT_WORDS. Redefine the macro to take an additional first
+ argument specifying the function to use. */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do \
+ { \
+ a += f (b, c, d) + correct_words[k] + T; \
+ CYCLIC (a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Add the starting values of the context. */
+ A += A_save;
+ B += B_save;
+ C += C_save;
+ D += D_save;
+ }
+
+ /* Put checksum in context given as argument. */
+ ctx->A = A;
+ ctx->B = B;
+ ctx->C = C;
+ ctx->D = D;
+}
diff --git a/3rdparty/elfutils/lib/md5.h b/3rdparty/elfutils/lib/md5.h
new file mode 100644
index 0000000..f2d0f30
--- /dev/null
+++ b/3rdparty/elfutils/lib/md5.h
@@ -0,0 +1,110 @@
+/* Declaration of functions and data types used for MD5 sum computing
+ library functions.
+ Copyright (C) 1995,1996,1997,1999-2001,2004,2005,2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1995.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _MD5_H
+#define _MD5_H 1
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#define MD5_DIGEST_SIZE 16
+#define MD5_BLOCK_SIZE 64
+
+typedef uint32_t md5_uint32;
+typedef uintptr_t md5_uintptr;
+
+/* Structure to save state of computation between the single steps. */
+struct md5_ctx
+{
+ md5_uint32 A;
+ md5_uint32 B;
+ md5_uint32 C;
+ md5_uint32 D;
+
+ md5_uint32 total[2];
+ md5_uint32 buflen;
+ char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+ (RFC 1321, 3.3: Step 3) */
+extern void md5_init_ctx (struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+ initialization function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is necessary that LEN is a multiple of 64!!! */
+extern void md5_process_block (const void *buffer, size_t len,
+ struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+ initialization function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is NOT required that LEN is a multiple of 64. */
+extern void md5_process_bytes (const void *buffer, size_t len,
+ struct md5_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+ in first 16 bytes following RESBUF. The result is always in little
+ endian byte order, so that a byte-wise output yields to the wanted
+ ASCII representation of the message digest.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 16 bytes following RESBUF. The result is
+ always in little endian byte order, so that a byte-wise output yields
+ to the wanted ASCII representation of the message digest.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
+
+
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+extern int md5_stream (FILE *stream, void *resblock);
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
+ result is always in little endian byte order, so that a byte-wise
+ output yields to the wanted ASCII representation of the message
+ digest. */
+extern void *md5_buffer (const char *buffer, size_t len, void *resblock);
+
+#endif /* md5.h */
diff --git a/3rdparty/elfutils/lib/next_prime.c b/3rdparty/elfutils/lib/next_prime.c
new file mode 100644
index 0000000..f2c921e
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+
+
+/* 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/3rdparty/elfutils/lib/sha1.c b/3rdparty/elfutils/lib/sha1.c
new file mode 100644
index 0000000..0e84562
--- /dev/null
+++ b/3rdparty/elfutils/lib/sha1.c
@@ -0,0 +1,391 @@
+/* Functions to compute SHA1 message digest of files or memory blocks.
+ according to the definition of SHA1 in FIPS 180-1 from April 1997.
+ Copyright (C) 2008-2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2008.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "sha1.h"
+#include "system.h"
+
+#define SWAP(n) BE32 (n)
+
+/* This array contains the bytes used to pad the buffer to the next
+ 64-byte boundary. */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
+
+
+/* Initialize structure containing state of computation. */
+void
+sha1_init_ctx (ctx)
+ struct sha1_ctx *ctx;
+{
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+ ctx->E = 0xc3d2e1f0;
+
+ ctx->total[0] = ctx->total[1] = 0;
+ ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 20 bytes following RESBUF. The result
+ must be in little endian byte order.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+void *
+sha1_read_ctx (ctx, resbuf)
+ const struct sha1_ctx *ctx;
+ void *resbuf;
+{
+ ((sha1_uint32 *) resbuf)[0] = SWAP (ctx->A);
+ ((sha1_uint32 *) resbuf)[1] = SWAP (ctx->B);
+ ((sha1_uint32 *) resbuf)[2] = SWAP (ctx->C);
+ ((sha1_uint32 *) resbuf)[3] = SWAP (ctx->D);
+ ((sha1_uint32 *) resbuf)[4] = SWAP (ctx->E);
+
+ return resbuf;
+}
+
+static void
+be64_copy (char *dest, uint64_t x)
+{
+ for (size_t i = 8; i-- > 0; x >>= 8)
+ dest[i] = (uint8_t) x;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+ prolog according to the standard and write the result to RESBUF.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+void *
+sha1_finish_ctx (ctx, resbuf)
+ struct sha1_ctx *ctx;
+ void *resbuf;
+{
+ /* Take yet unprocessed bytes into account. */
+ sha1_uint32 bytes = ctx->buflen;
+ size_t pad;
+
+ /* Now count remaining bytes. */
+ ctx->total[0] += bytes;
+ if (ctx->total[0] < bytes)
+ ++ctx->total[1];
+
+ pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+ memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+ /* Put the 64-bit file length in *bits* at the end of the buffer. */
+ const uint64_t bit_length = ((ctx->total[0] << 3)
+ + ((uint64_t) ((ctx->total[1] << 3) |
+ (ctx->total[0] >> 29)) << 32));
+ be64_copy (&ctx->buffer[bytes + pad], bit_length);
+
+ /* Process last bytes. */
+ sha1_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+ return sha1_read_ctx (ctx, resbuf);
+}
+
+
+void
+sha1_process_bytes (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct sha1_ctx *ctx;
+{
+ /* When we already have some bits in our internal buffer concatenate
+ both inputs first. */
+ if (ctx->buflen != 0)
+ {
+ size_t left_over = ctx->buflen;
+ size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+ memcpy (&ctx->buffer[left_over], buffer, add);
+ ctx->buflen += add;
+
+ if (ctx->buflen > 64)
+ {
+ sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+
+ ctx->buflen &= 63;
+ /* The regions in the following copy operation cannot overlap. */
+ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+ ctx->buflen);
+ }
+
+ buffer = (const char *) buffer + add;
+ len -= add;
+ }
+
+ /* Process available complete blocks. */
+ if (len >= 64)
+ {
+#if !_STRING_ARCH_unaligned
+/* To check alignment gcc has an appropriate operator. Other
+ compilers don't. */
+# if __GNUC__ >= 2
+# define UNALIGNED_P(p) (((sha1_uintptr) p) % __alignof__ (sha1_uint32) != 0)
+# else
+# define UNALIGNED_P(p) (((sha1_uintptr) p) % sizeof (sha1_uint32) != 0)
+# endif
+ if (UNALIGNED_P (buffer))
+ while (len > 64)
+ {
+ sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+ buffer = (const char *) buffer + 64;
+ len -= 64;
+ }
+ else
+#endif
+ {
+ sha1_process_block (buffer, len & ~63, ctx);
+ buffer = (const char *) buffer + (len & ~63);
+ len &= 63;
+ }
+ }
+
+ /* Move remaining bytes in internal buffer. */
+ if (len > 0)
+ {
+ size_t left_over = ctx->buflen;
+
+ memcpy (&ctx->buffer[left_over], buffer, len);
+ left_over += len;
+ if (left_over >= 64)
+ {
+ sha1_process_block (ctx->buffer, 64, ctx);
+ left_over -= 64;
+ memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+ }
+ ctx->buflen = left_over;
+ }
+}
+
+
+/* These are the four functions used in the four steps of the SHA1 algorithm
+ and defined in the FIPS 180-1. */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) (b ^ c ^ d)
+/* define FH(b, c, d) ((b & c) | (b & d) | (c & d)) */
+#define FH(b, c, d) (((b | c) & d) | (b & c))
+
+/* It is unfortunate that C does not provide an operator for cyclic
+ rotation. Hope the C compiler is smart enough. */
+#define CYCLIC(w, s) (((w) << s) | ((w) >> (32 - s)))
+
+/* Magic constants. */
+#define K0 0x5a827999
+#define K1 0x6ed9eba1
+#define K2 0x8f1bbcdc
+#define K3 0xca62c1d6
+
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+ It is assumed that LEN % 64 == 0. */
+
+void
+sha1_process_block (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct sha1_ctx *ctx;
+{
+ sha1_uint32 computed_words[16];
+#define W(i) computed_words[(i) % 16]
+ const sha1_uint32 *words = buffer;
+ size_t nwords = len / sizeof (sha1_uint32);
+ const sha1_uint32 *endp = words + nwords;
+ sha1_uint32 A = ctx->A;
+ sha1_uint32 B = ctx->B;
+ sha1_uint32 C = ctx->C;
+ sha1_uint32 D = ctx->D;
+ sha1_uint32 E = ctx->E;
+
+ /* First increment the byte count. FIPS 180-1 specifies the possible
+ length of the file up to 2^64 bits. Here we only compute the
+ number of bytes. Do a double word increment. */
+ ctx->total[0] += len;
+ if (ctx->total[0] < len)
+ ++ctx->total[1];
+
+ /* Process all bytes in the buffer with 64 bytes in each round of
+ the loop. */
+ while (words < endp)
+ {
+ sha1_uint32 A_save = A;
+ sha1_uint32 B_save = B;
+ sha1_uint32 C_save = C;
+ sha1_uint32 D_save = D;
+ sha1_uint32 E_save = E;
+
+ /* First round: using the given function, the context and a constant
+ the next context is computed. Because the algorithms processing
+ unit is a 32-bit word and it is determined to work on words in
+ little endian byte order we perhaps have to change the byte order
+ before the computation. */
+
+#define OP(i, a, b, c, d, e) \
+ do \
+ { \
+ W (i) = SWAP (*words); \
+ e = CYCLIC (a, 5) + FF (b, c, d) + e + W (i) + K0; \
+ ++words; \
+ b = CYCLIC (b, 30); \
+ } \
+ while (0)
+
+ /* Steps 0 to 15. */
+ OP (0, A, B, C, D, E);
+ OP (1, E, A, B, C, D);
+ OP (2, D, E, A, B, C);
+ OP (3, C, D, E, A, B);
+ OP (4, B, C, D, E, A);
+ OP (5, A, B, C, D, E);
+ OP (6, E, A, B, C, D);
+ OP (7, D, E, A, B, C);
+ OP (8, C, D, E, A, B);
+ OP (9, B, C, D, E, A);
+ OP (10, A, B, C, D, E);
+ OP (11, E, A, B, C, D);
+ OP (12, D, E, A, B, C);
+ OP (13, C, D, E, A, B);
+ OP (14, B, C, D, E, A);
+ OP (15, A, B, C, D, E);
+
+ /* For the remaining 64 steps we have a more complicated
+ computation of the input data-derived values. Redefine the
+ macro to take an additional second argument specifying the
+ function to use and a new last parameter for the magic
+ constant. */
+#undef OP
+#define OP(i, f, a, b, c, d, e, K) \
+ do \
+ { \
+ W (i) = CYCLIC (W (i - 3) ^ W (i - 8) ^ W (i - 14) ^ W (i - 16), 1);\
+ e = CYCLIC (a, 5) + f (b, c, d) + e + W (i) + K; \
+ b = CYCLIC (b, 30); \
+ } \
+ while (0)
+
+ /* Steps 16 to 19. */
+ OP (16, FF, E, A, B, C, D, K0);
+ OP (17, FF, D, E, A, B, C, K0);
+ OP (18, FF, C, D, E, A, B, K0);
+ OP (19, FF, B, C, D, E, A, K0);
+
+ /* Steps 20 to 39. */
+ OP (20, FG, A, B, C, D, E, K1);
+ OP (21, FG, E, A, B, C, D, K1);
+ OP (22, FG, D, E, A, B, C, K1);
+ OP (23, FG, C, D, E, A, B, K1);
+ OP (24, FG, B, C, D, E, A, K1);
+ OP (25, FG, A, B, C, D, E, K1);
+ OP (26, FG, E, A, B, C, D, K1);
+ OP (27, FG, D, E, A, B, C, K1);
+ OP (28, FG, C, D, E, A, B, K1);
+ OP (29, FG, B, C, D, E, A, K1);
+ OP (30, FG, A, B, C, D, E, K1);
+ OP (31, FG, E, A, B, C, D, K1);
+ OP (32, FG, D, E, A, B, C, K1);
+ OP (33, FG, C, D, E, A, B, K1);
+ OP (34, FG, B, C, D, E, A, K1);
+ OP (35, FG, A, B, C, D, E, K1);
+ OP (36, FG, E, A, B, C, D, K1);
+ OP (37, FG, D, E, A, B, C, K1);
+ OP (38, FG, C, D, E, A, B, K1);
+ OP (39, FG, B, C, D, E, A, K1);
+
+ /* Steps 40 to 59. */
+ OP (40, FH, A, B, C, D, E, K2);
+ OP (41, FH, E, A, B, C, D, K2);
+ OP (42, FH, D, E, A, B, C, K2);
+ OP (43, FH, C, D, E, A, B, K2);
+ OP (44, FH, B, C, D, E, A, K2);
+ OP (45, FH, A, B, C, D, E, K2);
+ OP (46, FH, E, A, B, C, D, K2);
+ OP (47, FH, D, E, A, B, C, K2);
+ OP (48, FH, C, D, E, A, B, K2);
+ OP (49, FH, B, C, D, E, A, K2);
+ OP (50, FH, A, B, C, D, E, K2);
+ OP (51, FH, E, A, B, C, D, K2);
+ OP (52, FH, D, E, A, B, C, K2);
+ OP (53, FH, C, D, E, A, B, K2);
+ OP (54, FH, B, C, D, E, A, K2);
+ OP (55, FH, A, B, C, D, E, K2);
+ OP (56, FH, E, A, B, C, D, K2);
+ OP (57, FH, D, E, A, B, C, K2);
+ OP (58, FH, C, D, E, A, B, K2);
+ OP (59, FH, B, C, D, E, A, K2);
+
+ /* Steps 60 to 79. */
+ OP (60, FG, A, B, C, D, E, K3);
+ OP (61, FG, E, A, B, C, D, K3);
+ OP (62, FG, D, E, A, B, C, K3);
+ OP (63, FG, C, D, E, A, B, K3);
+ OP (64, FG, B, C, D, E, A, K3);
+ OP (65, FG, A, B, C, D, E, K3);
+ OP (66, FG, E, A, B, C, D, K3);
+ OP (67, FG, D, E, A, B, C, K3);
+ OP (68, FG, C, D, E, A, B, K3);
+ OP (69, FG, B, C, D, E, A, K3);
+ OP (70, FG, A, B, C, D, E, K3);
+ OP (71, FG, E, A, B, C, D, K3);
+ OP (72, FG, D, E, A, B, C, K3);
+ OP (73, FG, C, D, E, A, B, K3);
+ OP (74, FG, B, C, D, E, A, K3);
+ OP (75, FG, A, B, C, D, E, K3);
+ OP (76, FG, E, A, B, C, D, K3);
+ OP (77, FG, D, E, A, B, C, K3);
+ OP (78, FG, C, D, E, A, B, K3);
+ OP (79, FG, B, C, D, E, A, K3);
+
+ /* Add the starting values of the context. */
+ A += A_save;
+ B += B_save;
+ C += C_save;
+ D += D_save;
+ E += E_save;
+ }
+
+ /* Put checksum in context given as argument. */
+ ctx->A = A;
+ ctx->B = B;
+ ctx->C = C;
+ ctx->D = D;
+ ctx->E = E;
+}
diff --git a/3rdparty/elfutils/lib/sha1.h b/3rdparty/elfutils/lib/sha1.h
new file mode 100644
index 0000000..05301c8
--- /dev/null
+++ b/3rdparty/elfutils/lib/sha1.h
@@ -0,0 +1,93 @@
+/* Declaration of functions and data types used for SHA1 sum computing
+ library functions.
+ Copyright (C) 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2008.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _SHA1_H
+#define _SHA1_H 1
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_BLOCK_SIZE 64
+
+typedef uint32_t sha1_uint32;
+typedef uintptr_t sha1_uintptr;
+
+/* Structure to save state of computation between the single steps. */
+struct sha1_ctx
+{
+ sha1_uint32 A;
+ sha1_uint32 B;
+ sha1_uint32 C;
+ sha1_uint32 D;
+ sha1_uint32 E;
+
+ sha1_uint32 total[2];
+ sha1_uint32 buflen;
+ char buffer[128] __attribute__ ((__aligned__ (__alignof__ (sha1_uint32))));
+};
+
+/* Initialize structure containing state of computation. */
+extern void sha1_init_ctx (struct sha1_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+ initialization function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is necessary that LEN is a multiple of 64!!! */
+extern void sha1_process_block (const void *buffer, size_t len,
+ struct sha1_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+ initialization function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is NOT required that LEN is a multiple of 64. */
+extern void sha1_process_bytes (const void *buffer, size_t len,
+ struct sha1_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+ in first 20 bytes following RESBUF. The result is always in little
+ endian byte order, so that a byte-wise output yields to the wanted
+ ASCII representation of the message digest.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 20 bytes following RESBUF. The result is
+ always in little endian byte order, so that a byte-wise output yields
+ to the wanted ASCII representation of the message digest.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
+
+#endif /* sha1.h */
diff --git a/3rdparty/elfutils/lib/system.h b/3rdparty/elfutils/lib/system.h
new file mode 100644
index 0000000..f31cfd0
--- /dev/null
+++ b/3rdparty/elfutils/lib/system.h
@@ -0,0 +1,185 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef LIB_SYSTEM_H
+#define LIB_SYSTEM_H 1
+
+#include <argp.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <unistd.h>
+
+#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
+
+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);
+
+/* A special gettext function we use if the strings are too short. */
+#define sgettext(Str) \
+ ({ const char *__res = strrchr (gettext (Str), '|'); \
+ __res ? __res + 1 : Str; })
+
+#define gettext_noop(Str) Str
+
+
+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, 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, 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, buf + recvd, len - recvd,
+ off + recvd));
+ if (ret <= 0)
+ return ret < 0 ? ret : recvd;
+
+ recvd += ret;
+ }
+ while ((size_t) recvd < len);
+
+ return recvd;
+}
+
+
+/* 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")
+
+
+/* The demangler from libstdc++. */
+extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
+ size_t *length, int *status);
+
+
+
+/* Color handling. */
+
+/* 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_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[];
+
+/* 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/3rdparty/elfutils/lib/xmalloc.c b/3rdparty/elfutils/lib/xmalloc.c
new file mode 100644
index 0000000..27ccab9
--- /dev/null
+++ b/3rdparty/elfutils/lib/xmalloc.c
@@ -0,0 +1,84 @@
+/* Convenience functions for allocation.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <libintl.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "system.h"
+
+#ifndef _
+# define _(str) gettext (str)
+#endif
+
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+void *
+xmalloc (n)
+ 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 (n, s)
+ size_t n, 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 (p, n)
+ void *p;
+ size_t n;
+{
+ p = realloc (p, n);
+ if (p == NULL)
+ error (EXIT_FAILURE, 0, _("memory exhausted"));
+ return p;
+}
diff --git a/3rdparty/elfutils/lib/xstrdup.c b/3rdparty/elfutils/lib/xstrdup.c
new file mode 100644
index 0000000..d9d6010
--- /dev/null
+++ b/3rdparty/elfutils/lib/xstrdup.c
@@ -0,0 +1,43 @@
+/* Convenience function for string allocation.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "system.h"
+
+
+/* Return a newly allocated copy of STRING. */
+char *
+xstrdup (string)
+ const char *string;
+{
+ return strcpy (xmalloc (strlen (string) + 1), string);
+}
diff --git a/3rdparty/elfutils/lib/xstrndup.c b/3rdparty/elfutils/lib/xstrndup.c
new file mode 100644
index 0000000..52304e6
--- /dev/null
+++ b/3rdparty/elfutils/lib/xstrndup.c
@@ -0,0 +1,47 @@
+/* Convenience function for string allocation.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "system.h"
+
+
+/* Return a newly allocated copy of STRING. */
+char *
+xstrndup (string, n)
+ 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/3rdparty/elfutils/libasm/asm_abort.c b/3rdparty/elfutils/libasm/asm_abort.c
new file mode 100644
index 0000000..ef55ee9
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_abort.c
@@ -0,0 +1,61 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libasmP.h>
+#include <libelf.h>
+
+
+int
+asm_abort (ctx)
+ 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/3rdparty/elfutils/libasm/asm_addint16.c b/3rdparty/elfutils/libasm/asm_addint16.c
new file mode 100644
index 0000000..4ae4597
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define SIZE 16
+
+#include "asm_addint8.c"
diff --git a/3rdparty/elfutils/libasm/asm_addint32.c b/3rdparty/elfutils/libasm/asm_addint32.c
new file mode 100644
index 0000000..776cf6f
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define SIZE 32
+
+#include "asm_addint8.c"
diff --git a/3rdparty/elfutils/libasm/asm_addint64.c b/3rdparty/elfutils/libasm/asm_addint64.c
new file mode 100644
index 0000000..ee33834
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define SIZE 64
+
+#include "asm_addint8.c"
diff --git a/3rdparty/elfutils/libasm/asm_addint8.c b/3rdparty/elfutils/libasm/asm_addint8.c
new file mode 100644
index 0000000..ec05b8d
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_addint8.c
@@ -0,0 +1,123 @@
+/* Add integer to a section.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <libasmP.h>
+
+#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, num)
+ 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/3rdparty/elfutils/libasm/asm_addsleb128.c b/3rdparty/elfutils/libasm/asm_addsleb128.c
new file mode 100644
index 0000000..3692789
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_addsleb128.c
@@ -0,0 +1,99 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <libasmP.h>
+
+
+int
+asm_addsleb128 (asmscn, num)
+ 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/3rdparty/elfutils/libasm/asm_addstrz.c b/3rdparty/elfutils/libasm/asm_addstrz.c
new file mode 100644
index 0000000..87663f3
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_addstrz.c
@@ -0,0 +1,128 @@
+/* Add string to a section.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libasmP.h>
+
+
+/* Add zero terminated string STR of size LEN to (sub)section ASMSCN. */
+int
+asm_addstrz (asmscn, str, len)
+ 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/3rdparty/elfutils/libasm/asm_adduint16.c b/3rdparty/elfutils/libasm/asm_adduint16.c
new file mode 100644
index 0000000..65a1303
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define SIZE 16
+
+#include "asm_adduint8.c"
diff --git a/3rdparty/elfutils/libasm/asm_adduint32.c b/3rdparty/elfutils/libasm/asm_adduint32.c
new file mode 100644
index 0000000..9a3ec6d
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define SIZE 32
+
+#include "asm_adduint8.c"
diff --git a/3rdparty/elfutils/libasm/asm_adduint64.c b/3rdparty/elfutils/libasm/asm_adduint64.c
new file mode 100644
index 0000000..b2c57a4
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define SIZE 64
+
+#include "asm_adduint8.c"
diff --git a/3rdparty/elfutils/libasm/asm_adduint8.c b/3rdparty/elfutils/libasm/asm_adduint8.c
new file mode 100644
index 0000000..30641b8
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_adduint8.c
@@ -0,0 +1,56 @@
+/* Add unsigned integer to a section.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libasmP.h>
+
+#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, num)
+ AsmScn_t *asmscn;
+ UTYPE(SIZE) num;
+{
+ return INTUSE(FCT(SIZE)) (asmscn, (TYPE(SIZE)) num);
+}
diff --git a/3rdparty/elfutils/libasm/asm_adduleb128.c b/3rdparty/elfutils/libasm/asm_adduleb128.c
new file mode 100644
index 0000000..a3a8573
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_adduleb128.c
@@ -0,0 +1,95 @@
+/* Add integer to a section.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <string.h>
+
+#include "libasmP.h"
+
+
+int
+asm_adduleb128 (asmscn, num)
+ 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/3rdparty/elfutils/libasm/asm_align.c b/3rdparty/elfutils/libasm/asm_align.c
new file mode 100644
index 0000000..2025b02
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_align.c
@@ -0,0 +1,179 @@
+/* Align section.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/param.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+int
+asm_align (asmscn, value)
+ 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
+__libasm_ensure_section_space (asmscn, len)
+ 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 *) malloc (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 *) malloc (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/3rdparty/elfutils/libasm/asm_begin.c b/3rdparty/elfutils/libasm/asm_begin.c
new file mode 100644
index 0000000..48842d3
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_begin.c
@@ -0,0 +1,184 @@
+/* Create descriptor for assembling.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gelf.h>
+#include "libasmP.h"
+#include <system.h>
+
+
+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;
+ }
+
+ __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 endianess 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 = ebl_strtabinit (true);
+ result->symbol_strtab = ebl_strtabinit (true);
+
+ /* We have no section groups so far. */
+ result->groups = NULL;
+ result->ngroups = 0;
+
+ return result;
+}
+
+
+AsmCtx_t *
+asm_begin (fname, ebl, textp)
+ 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/3rdparty/elfutils/libasm/asm_end.c b/3rdparty/elfutils/libasm/asm_end.c
new file mode 100644
index 0000000..f4145a7
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_end.c
@@ -0,0 +1,613 @@
+/* Finalize operations on the assembler context, free all resources.
+ Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <libasmP.h>
+#include <libelf.h>
+#include <system.h>
+
+
+static int
+text_end (AsmCtx_t *ctx __attribute__ ((unused)))
+{
+ if (fclose (ctx->out.file) != 0)
+ {
+ __libasm_seterrno (ASM_E_IOERROR);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+binary_end (AsmCtx_t *ctx)
+{
+ void *symtab = NULL;
+ struct Ebl_Strent *symscn_strent = NULL;
+ struct Ebl_Strent *strscn_strent = NULL;
+ struct Ebl_Strent *xndxscn_strent = NULL;
+ Elf_Scn *shstrscn;
+ struct Ebl_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 = ebl_strtabadd (ctx->section_strtab, ".symtab", 8);
+ strscn_strent = ebl_strtabadd (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);
+
+ ebl_strtabfinalize (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 (ebl_string (sym->strent)))
+ {
+ assert (ptr_local <= ptr_nonlocal);
+
+ syment.st_name = ebl_strtaboffset (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 = ebl_strtabadd (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 setion
+ 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 = ebl_strtabadd (ctx->section_strtab, ".shstrtab", 10);
+
+ ebl_strtabfinalize (ctx->section_strtab, shstrtabdata);
+
+ shdr->sh_type = SHT_STRTAB;
+ assert (shdr->sh_entsize == 0);
+ shdr->sh_name = ebl_strtaboffset (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 = ebl_strtaboffset (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 = ebl_strtaboffset (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 = ebl_strtaboffset (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 = ebl_strtaboffset (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 = ebl_strtaboffset (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);
+
+ gelf_update_ehdr (ctx->out.elf, ehdr);
+
+ /* 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 (ctx)
+ 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
+__libasm_finictx (ctx)
+ 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. */
+ ebl_strtabfree (ctx->section_strtab);
+ ebl_strtabfree (ctx->symbol_strtab);
+ }
+
+ /* Initialize the lock. */
+ rwlock_fini (ctx->lock);
+
+ /* Finally free the data structure. */
+ free (ctx);
+}
diff --git a/3rdparty/elfutils/libasm/asm_error.c b/3rdparty/elfutils/libasm/asm_error.c
new file mode 100644
index 0000000..300a798
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_error.c
@@ -0,0 +1,96 @@
+/* Error handling in libasm.
+ Copyright (C) 2002, 2004, 2005, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#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
+__libasm_seterrno (value)
+ 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 (error)
+ 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/3rdparty/elfutils/libasm/asm_fill.c b/3rdparty/elfutils/libasm/asm_fill.c
new file mode 100644
index 0000000..6b92bc3
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_fill.c
@@ -0,0 +1,77 @@
+/* Determine fill pattern for a section.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+int
+asm_fill (asmscn, bytes, len)
+ 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/3rdparty/elfutils/libasm/asm_getelf.c b/3rdparty/elfutils/libasm/asm_getelf.c
new file mode 100644
index 0000000..edeff13
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_getelf.c
@@ -0,0 +1,44 @@
+/* Return ELF descriptor associated with the assembler context.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include <libasmP.h>
+
+
+Elf *
+asm_getelf (ctx)
+ AsmCtx_t *ctx;
+{
+ return ctx != NULL ? ctx->out.elf : NULL;
+}
diff --git a/3rdparty/elfutils/libasm/asm_newabssym.c b/3rdparty/elfutils/libasm/asm_newabssym.c
new file mode 100644
index 0000000..4e59901
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newabssym.c
@@ -0,0 +1,136 @@
+/* Create new ABS symbol.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+/* Object for special COMMON section. */
+static const AsmScn_t __libasm_abs_scn =
+ {
+ .data = {
+ .main = {
+ .scn = ASM_ABS_SCN
+ }
+ }
+ };
+
+
+AsmSym_t *
+asm_newabssym (ctx, name, size, value, type, binding)
+ 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 = ebl_strtabadd (ctx->symbol_strtab, name, 0);
+
+ /* 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/3rdparty/elfutils/libasm/asm_newcomsym.c b/3rdparty/elfutils/libasm/asm_newcomsym.c
new file mode 100644
index 0000000..7a578e0
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newcomsym.c
@@ -0,0 +1,117 @@
+/* Create new COMMON symbol.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+/* Object for special COMMON section. */
+static const AsmScn_t __libasm_com_scn =
+ {
+ .data = {
+ .main = {
+ .scn = ASM_COM_SCN
+ }
+ }
+ };
+
+
+AsmSym_t *
+asm_newcomsym (ctx, name, size, align)
+ 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 = ebl_strtabadd (ctx->symbol_strtab, name, 0);
+
+ /* 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/3rdparty/elfutils/libasm/asm_newscn.c b/3rdparty/elfutils/libasm/asm_newscn.c
new file mode 100644
index 0000000..ece7f5c
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newscn.c
@@ -0,0 +1,215 @@
+/* Create new section in output file.
+ Copyright (C) 2002-2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <libelf.h>
+#include <system.h>
+
+
+/* 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 = ebl_strtabadd (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 (ctx, scnname, type, flags)
+ 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/3rdparty/elfutils/libasm/asm_newscn_ingrp.c b/3rdparty/elfutils/libasm/asm_newscn_ingrp.c
new file mode 100644
index 0000000..6ef7cb9
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newscn_ingrp.c
@@ -0,0 +1,81 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#include "libasmP.h"
+
+
+AsmScn_t *
+asm_newscn_ingrp (ctx, scnname, type, flags, grp)
+ 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/3rdparty/elfutils/libasm/asm_newscngrp.c b/3rdparty/elfutils/libasm/asm_newscngrp.c
new file mode 100644
index 0000000..2808e69
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newscngrp.c
@@ -0,0 +1,105 @@
+/* Create new section group.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libasmP.h"
+#include <system.h>
+
+
+
+AsmScnGrp_t *
+asm_newscngrp (ctx, grpname, signature, flags)
+ 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 = ebl_strtabadd (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/3rdparty/elfutils/libasm/asm_newsubscn.c b/3rdparty/elfutils/libasm/asm_newsubscn.c
new file mode 100644
index 0000000..a83607a
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newsubscn.c
@@ -0,0 +1,99 @@
+/* Create new subsection section in given section.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+AsmScn_t *
+asm_newsubscn (asmscn, nr)
+ 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/3rdparty/elfutils/libasm/asm_newsym.c b/3rdparty/elfutils/libasm/asm_newsym.c
new file mode 100644
index 0000000..deca08a
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_newsym.c
@@ -0,0 +1,138 @@
+/* Define new symbol for current position in given section.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+AsmSym_t *
+asm_newsym (asmscn, name, size, type, binding)
+ AsmScn_t *asmscn;
+ const char *name;
+ GElf_Xword size;
+ int type;
+ int binding;
+{
+#define TEMPSYMLEN 10
+ 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 = ebl_strtabadd (asmscn->ctx->symbol_strtab,
+ memcpy (result + 1, name, name_len), 0);
+
+ 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
+ ebl_strtabadd 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/3rdparty/elfutils/libasm/asm_scngrp_newsignature.c b/3rdparty/elfutils/libasm/asm_scngrp_newsignature.c
new file mode 100644
index 0000000..d87f4a4
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asm_scngrp_newsignature.c
@@ -0,0 +1,48 @@
+/* Update signature of section group.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libasmP.h"
+
+
+int
+asm_scngrp_newsignature (grp, signature)
+ AsmScnGrp_t *grp;
+ AsmSym_t *signature;
+{
+ if (grp == NULL || signature == NULL)
+ return 1;
+
+ grp->signature = signature;
+
+ return 0;
+}
diff --git a/3rdparty/elfutils/libasm/asmheaders.pri b/3rdparty/elfutils/libasm/asmheaders.pri
new file mode 100644
index 0000000..5107045
--- /dev/null
+++ b/3rdparty/elfutils/libasm/asmheaders.pri
@@ -0,0 +1,6 @@
+HEADERS += \
+ $$PWD/libasm.h \
+ $$PWD/libasmP.h \
+ $$PWD/symbolhash.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/libasm/disasm_begin.c b/3rdparty/elfutils/libasm/disasm_begin.c
new file mode 100644
index 0000000..d00852b
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#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/3rdparty/elfutils/libasm/disasm_cb.c b/3rdparty/elfutils/libasm/disasm_cb.c
new file mode 100644
index 0000000..eb3689c
--- /dev/null
+++ b/3rdparty/elfutils/libasm/disasm_cb.c
@@ -0,0 +1,179 @@
+/* Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#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. */
+ 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 (startp, end, addr, fmt, outcb, getsym, outcbarg,
+ symcbarg);
+}
+INTDEF (disasm_cb)
diff --git a/3rdparty/elfutils/libasm/disasm_end.c b/3rdparty/elfutils/libasm/disasm_end.c
new file mode 100644
index 0000000..6878030
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libasmP.h"
+
+
+int
+disasm_end (DisasmCtx_t *ctx)
+{
+ free (ctx);
+
+ return 0;
+}
diff --git a/3rdparty/elfutils/libasm/disasm_str.c b/3rdparty/elfutils/libasm/disasm_str.c
new file mode 100644
index 0000000..5b0bb29
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#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/3rdparty/elfutils/libasm/libasm.h b/3rdparty/elfutils/libasm/libasm.h
new file mode 100644
index 0000000..5c61224
--- /dev/null
+++ b/3rdparty/elfutils/libasm/libasm.h
@@ -0,0 +1,202 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBASM_H
+#define _LIBASM_H 1
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <libebl.h>
+
+
+/* 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 <elf.h>, 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/3rdparty/elfutils/libasm/libasm.pro b/3rdparty/elfutils/libasm/libasm.pro
new file mode 100644
index 0000000..a6e9f1a
--- /dev/null
+++ b/3rdparty/elfutils/libasm/libasm.pro
@@ -0,0 +1,40 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../asm
+
+include(../elfutils.pri)
+include(../libebl/eblheaders.pri)
+include(asmheaders.pri)
+
+SOURCES += \
+ $$PWD/asm_abort.c \
+ $$PWD/asm_addint8.c \
+ $$PWD/asm_addint16.c \
+ $$PWD/asm_addint32.c \
+ $$PWD/asm_addint64.c \
+ $$PWD/asm_addsleb128.c \
+ $$PWD/asm_addstrz.c \
+ $$PWD/asm_adduint8.c \
+ $$PWD/asm_adduint16.c \
+ $$PWD/asm_adduint32.c \
+ $$PWD/asm_adduint64.c \
+ $$PWD/asm_adduleb128.c \
+ $$PWD/asm_align.c \
+ $$PWD/asm_begin.c \
+ $$PWD/asm_end.c \
+ $$PWD/asm_error.c \
+ $$PWD/asm_fill.c \
+ $$PWD/asm_getelf.c \
+ $$PWD/asm_newabssym.c \
+ $$PWD/asm_newcomsym.c \
+ $$PWD/asm_newscn_ingrp.c \
+ $$PWD/asm_newscn.c \
+ $$PWD/asm_newscngrp.c \
+ $$PWD/asm_newsubscn.c \
+ $$PWD/asm_newsym.c \
+ $$PWD/asm_scngrp_newsignature.c \
+ $$PWD/disasm_begin.c \
+ $$PWD/disasm_cb.c \
+ $$PWD/disasm_end.c \
+ $$PWD/disasm_str.c \
+ $$PWD/symbolhash.c
diff --git a/3rdparty/elfutils/libasm/libasmP.h b/3rdparty/elfutils/libasm/libasmP.h
new file mode 100644
index 0000000..49b6484
--- /dev/null
+++ b/3rdparty/elfutils/libasm/libasmP.h
@@ -0,0 +1,307 @@
+/* Internal definitions for libasm.
+ Copyright (C) 2002, 2004, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBASMP_H
+#define _LIBASMP_H 1
+
+#include <stdio.h>
+
+#include <libasm.h>
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* 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 <symbolhash.h>
+
+
+/* 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. */
+ struct Ebl_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. */
+ struct Ebl_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. */
+ struct Ebl_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. */
+ struct Ebl_Strent *strent;
+};
+
+
+/* Descriptor for section group. */
+struct AsmScnGrp
+{
+ /* Entry in the section header string table. */
+ struct Ebl_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) (strncmp (name, ".L", 2) != 0)
+
+#endif /* libasmP.h */
diff --git a/3rdparty/elfutils/libasm/symbolhash.c b/3rdparty/elfutils/libasm/symbolhash.c
new file mode 100644
index 0000000..1c95418
--- /dev/null
+++ b/3rdparty/elfutils/libasm/symbolhash.c
@@ -0,0 +1,54 @@
+/* Symbol hash table implementation.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libasmP.h>
+#include <libebl.h>
+
+/* 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 (ebl_string ((a)->strent), ebl_string ((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/3rdparty/elfutils/libasm/symbolhash.h b/3rdparty/elfutils/libasm/symbolhash.h
new file mode 100644
index 0000000..a5bceff
--- /dev/null
+++ b/3rdparty/elfutils/libasm/symbolhash.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#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 (ebl_string ((a)->strent), ebl_string ((b)->strent))
+#include <dynamicsizehash.h>
+
+#endif /* symbolhash.h */
diff --git a/3rdparty/elfutils/libdw/cfi.c b/3rdparty/elfutils/libdw/cfi.c
new file mode 100644
index 0000000..632e91d
--- /dev/null
+++ b/3rdparty/elfutils/libdw/cfi.c
@@ -0,0 +1,504 @@
+/* CFI program execution.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "../libebl/libebl.h"
+#include "cfi.h"
+#include "memory-access.h"
+#include "encoded-value.h"
+#include "system.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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;
+}
+
+/* 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;
+ inline bool enough_registers (Dwarf_Word reg)
+ {
+ if (fs->nregs <= reg)
+ {
+ size_t size = offsetof (Dwarf_Frame, regs[reg + 1]);
+ Dwarf_Frame *bigger = realloc (fs, 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;
+ fs = bigger;
+ }
+ }
+ return true;
+ }
+
+ inline void require_cfa_offset (void)
+ {
+ if (unlikely (fs->cfa_rule != cfa_offset))
+ fs->cfa_rule = cfa_invalid;
+ }
+
+#define register_rule(regno, r_rule, r_value) do { \
+ if (unlikely (! enough_registers (regno))) \
+ 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++;
+ 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->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->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);
+ 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);
+ 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)))
+ 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:
+ /* 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)))
+ 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 = (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/3rdparty/elfutils/libdw/cfi.h b/3rdparty/elfutils/libdw/cfi.h
new file mode 100644
index 0000000..98ac6cf
--- /dev/null
+++ b/3rdparty/elfutils/libdw/cfi.h
@@ -0,0 +1,235 @@
+/* Internal definitions for libdw CFI interpreter.
+ Copyright (C) 2009-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 <http://www.gnu.org/licenses/>. */
+
+#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;
+ Dwarf_Addr search_table_vaddr;
+ size_t search_table_entries;
+ uint8_t search_table_encoding;
+
+ /* 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/3rdparty/elfutils/libdw/cie.c b/3rdparty/elfutils/libdw/cie.c
new file mode 100644
index 0000000..1b0aae7
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include "encoded-value.h"
+#include <assert.h>
+#include <search.h>
+#include <stdlib.h>
+
+
+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/3rdparty/elfutils/libdw/dwarf.h b/3rdparty/elfutils/libdw/dwarf.h
new file mode 100644
index 0000000..da8cf3a
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf.h
@@ -0,0 +1,798 @@
+/* This file defines standard DWARF types, structures, and macros.
+ Copyright (C) 2000-2011, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _DWARF_H
+#define _DWARF_H 1
+
+/* 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,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ 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,
+ 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. */
+ 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_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,
+ DW_AT_ordering = 0x09,
+ DW_AT_subscr_data = 0x0a,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_element_list = 0x0f,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_member = 0x14,
+ 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,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_bit_stride = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ 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,
+ 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,
+
+ /* DWARF5 attribute values. */
+ DW_AT_noreturn = 0x87,
+
+ 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_macros = 0x2119,
+ DW_AT_GNU_deleted = 0x211a,
+
+ DW_AT_hi_user = 0x3fff
+ };
+
+
+/* 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_ref_sig8 = 0x20,
+
+ 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. */
+
+ /* 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,
+
+ 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_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_PL1 = 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_Go = 0x0016, /* Go */
+ DW_LANG_C_plus_plus_11 = 0x001a, /* ISO C++:2011 */
+ DW_LANG_C11 = 0x001d, /* ISO C:2011 */
+ DW_LANG_C_plus_plus_14 = 0x0021, /* ISO C++:2014 */
+
+
+ DW_LANG_lo_user = 0x8000,
+ DW_LANG_Mips_Assembler = 0x8001, /* Assembler */
+ DW_LANG_hi_user = 0xffff
+ };
+
+
+/* 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. */
+enum
+ {
+ DW_CC_normal = 0x1,
+ DW_CC_program = 0x2,
+ DW_CC_nocall = 0x3,
+ 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 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. GNU/DWARF5 extension. */
+enum
+ {
+ DW_MACRO_GNU_define = 0x01,
+ DW_MACRO_GNU_undef = 0x02,
+ DW_MACRO_GNU_start_file = 0x03,
+ DW_MACRO_GNU_end_file = 0x04,
+ DW_MACRO_GNU_define_indirect = 0x05,
+ DW_MACRO_GNU_undef_indirect = 0x06,
+ DW_MACRO_GNU_transparent_include = 0x07,
+ DW_MACRO_GNU_lo_user = 0xe0,
+ DW_MACRO_GNU_hi_user = 0xff
+ };
+
+
+/* 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_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 minium 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/3rdparty/elfutils/libdw/dwarf_abbrev_hash.c b/3rdparty/elfutils/libdw/dwarf_abbrev_hash.c
new file mode 100644
index 0000000..f52f5ad
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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 <dynamicsizehash.c>
+
+#undef next_prime
+#define next_prime attribute_hidden __libdwarf_next_prime
+#include "../lib/next_prime.c"
diff --git a/3rdparty/elfutils/libdw/dwarf_abbrev_hash.h b/3rdparty/elfutils/libdw/dwarf_abbrev_hash.h
new file mode 100644
index 0000000..d2f02cc
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_abbrev_hash.h
@@ -0,0 +1,39 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _DWARF_ABBREV_HASH_H
+#define _DWARF_ABBREV_HASH_H 1
+
+#define NAME Dwarf_Abbrev_Hash
+#define TYPE Dwarf_Abbrev *
+#define COMPARE(a, b) (0)
+
+#include <dynamicsizehash.h>
+
+#endif /* dwarf_abbrev_hash.h */
diff --git a/3rdparty/elfutils/libdw/dwarf_abbrevhaschildren.c b/3rdparty/elfutils/libdw/dwarf_abbrevhaschildren.c
new file mode 100644
index 0000000..4a83e31
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_abbrevhaschildren.c
@@ -0,0 +1,44 @@
+/* Return true if abbreviation is children flag set.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_abbrevhaschildren (abbrev)
+ Dwarf_Abbrev *abbrev;
+{
+ return abbrev == NULL ? -1 : abbrev->has_children;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_addrdie.c b/3rdparty/elfutils/libdw/dwarf_addrdie.c
new file mode 100644
index 0000000..94eb148
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_addrdie.c
@@ -0,0 +1,54 @@
+/* Return CU DIE containing given address.
+ Copyright (C) 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+Dwarf_Die *
+dwarf_addrdie (dbg, addr, result)
+ 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/3rdparty/elfutils/libdw/dwarf_aggregate_size.c b/3rdparty/elfutils/libdw/dwarf_aggregate_size.c
new file mode 100644
index 0000000..667c274
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_aggregate_size.c
@@ -0,0 +1,244 @@
+/* Compute size of an aggregate type from DWARF.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#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
+array_size (Dwarf_Die *die, Dwarf_Word *size,
+ Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
+{
+ Dwarf_Word eltsize;
+ if (INTUSE(dwarf_aggregate_size) (get_type (die, attr_mem, type_mem),
+ &eltsize) != 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 total = 0;
+ 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
+ {
+ /* Determine default lower bound from language,
+ as per "4.12 Subrange Type Entries". */
+ Dwarf_Die cu = CUDIE (die->cu);
+ switch (INTUSE(dwarf_srclang) (&cu))
+ {
+ 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_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_UPC:
+ case DW_LANG_Go:
+ lower = 0;
+ break;
+
+ 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_Pascal83:
+ case DW_LANG_Modula2:
+ case DW_LANG_PL1:
+ lower = 1;
+ break;
+
+ default:
+ 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;
+ }
+
+ /* This is a subrange_type or enumeration_type and we've set COUNT.
+ Now determine the stride for this array dimension. */
+ Dwarf_Word stride = eltsize;
+ if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_byte_stride,
+ attr_mem) != NULL)
+ {
+ if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
+ return -1;
+ }
+ else if (INTUSE(dwarf_attr_integrate) (&child, 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;
+ }
+
+ any = true;
+ total += stride * count;
+ }
+ while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
+
+ if (!any)
+ return -1;
+
+ *size = total;
+ return 0;
+}
+
+static int
+aggregate_size (Dwarf_Die *die, Dwarf_Word *size, Dwarf_Die *type_mem)
+{
+ Dwarf_Attribute attr_mem;
+
+ 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:
+ return aggregate_size (get_type (die, &attr_mem, type_mem),
+ size, type_mem); /* Tail call. */
+
+ case DW_TAG_array_type:
+ return array_size (die, size, &attr_mem, type_mem);
+
+ /* 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 (die, size)
+ Dwarf_Die *die;
+ Dwarf_Word *size;
+{
+ Dwarf_Die type_mem;
+
+ if (INTUSE (dwarf_peel_type) (die, die) != 0)
+ return -1;
+
+ return aggregate_size (die, size, &type_mem);
+}
+INTDEF (dwarf_aggregate_size)
+OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144)
+NEW_VERSION (dwarf_aggregate_size, ELFUTILS_0.161)
diff --git a/3rdparty/elfutils/libdw/dwarf_arrayorder.c b/3rdparty/elfutils/libdw/dwarf_arrayorder.c
new file mode 100644
index 0000000..759fa4d
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_arrayorder.c
@@ -0,0 +1,50 @@
+/* Return array order attribute of DIE.
+ Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_arrayorder (die)
+ 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/3rdparty/elfutils/libdw/dwarf_attr.c b/3rdparty/elfutils/libdw/dwarf_attr.c
new file mode 100644
index 0000000..f247c1a
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_attr.c
@@ -0,0 +1,55 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Attribute *
+dwarf_attr (die, search_name, result)
+ 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/3rdparty/elfutils/libdw/dwarf_attr_integrate.c b/3rdparty/elfutils/libdw/dwarf_attr_integrate.c
new file mode 100644
index 0000000..812d74b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_attr_integrate.c
@@ -0,0 +1,60 @@
+/* Return specific DWARF attribute of a DIE, integrating indirections.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+Dwarf_Attribute *
+dwarf_attr_integrate (Dwarf_Die *die, unsigned int search_name,
+ Dwarf_Attribute *result)
+{
+ Dwarf_Die die_mem;
+
+ 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);
+
+ return NULL;
+}
+INTDEF (dwarf_attr_integrate)
diff --git a/3rdparty/elfutils/libdw/dwarf_begin.c b/3rdparty/elfutils/libdw/dwarf_begin.c
new file mode 100644
index 0000000..9f3050f
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_begin.c
@@ -0,0 +1,101 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include <libdwP.h>
+
+
+Dwarf *
+dwarf_begin (fd, cmd)
+ 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 stat64 st;
+
+ if (fstat64 (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/3rdparty/elfutils/libdw/dwarf_begin_elf.c b/3rdparty/elfutils/libdw/dwarf_begin_elf.c
new file mode 100644
index 0000000..4c49ce2
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_begin_elf.c
@@ -0,0 +1,395 @@
+/* Create descriptor from ELF descriptor for processing file.
+ Copyright (C) 2002-2011, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "libdwP.h"
+
+#if USE_ZLIB
+# include <endian.h>
+# define crc32 loser_crc32
+# include <zlib.h>
+# undef crc32
+#endif
+
+
+/* Section names. */
+static const char dwarf_scnnames[IDX_last][18] =
+{
+ [IDX_debug_info] = ".debug_info",
+ [IDX_debug_types] = ".debug_types",
+ [IDX_debug_abbrev] = ".debug_abbrev",
+ [IDX_debug_aranges] = ".debug_aranges",
+ [IDX_debug_line] = ".debug_line",
+ [IDX_debug_frame] = ".debug_frame",
+ [IDX_debug_loc] = ".debug_loc",
+ [IDX_debug_pubnames] = ".debug_pubnames",
+ [IDX_debug_str] = ".debug_str",
+ [IDX_debug_macinfo] = ".debug_macinfo",
+ [IDX_debug_macro] = ".debug_macro",
+ [IDX_debug_ranges] = ".debug_ranges",
+ [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
+};
+#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
+
+static Dwarf *
+check_section (Dwarf *result, GElf_Ehdr *ehdr, 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, ehdr->e_shstrndx,
+ shdr->sh_name);
+ if (scnname == NULL)
+ {
+ /* The section name must be valid. Otherwise is the ELF file
+ invalid. */
+ err:
+ __libdw_free_zdata (result);
+ 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;
+ for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
+ if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
+ {
+ /* Found it. Remember where the data is. */
+ if (unlikely (result->sectiondata[cnt] != NULL))
+ /* A section appears twice. That's bad. We ignore the section. */
+ break;
+
+ /* Get the section data. */
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data != NULL && data->d_size != 0)
+ /* Yep, there is actually data available. */
+ result->sectiondata[cnt] = data;
+
+ break;
+ }
+#if USE_ZLIB
+ else if (scnname[0] == '.' && scnname[1] == 'z'
+ && strcmp (&scnname[2], &dwarf_scnnames[cnt][1]) == 0)
+ {
+ /* A compressed section. */
+
+ if (unlikely (result->sectiondata[cnt] != NULL))
+ /* A section appears twice. That's bad. We ignore the section. */
+ break;
+
+ /* Get the section data. */
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data != NULL && data->d_size != 0)
+ {
+ /* There is a 12-byte header of "ZLIB" followed by
+ an 8-byte big-endian size. */
+
+ if (unlikely (data->d_size < 4 + 8)
+ || unlikely (memcmp (data->d_buf, "ZLIB", 4) != 0))
+ break;
+
+ uint64_t size;
+ memcpy (&size, data->d_buf + 4, sizeof size);
+ size = be64toh (size);
+
+ /* Check for unsigned overflow so malloc always allocated
+ enough memory for both the Elf_Data header and the
+ uncompressed section data. */
+ if (unlikely (sizeof (Elf_Data) + size < size))
+ break;
+
+ Elf_Data *zdata = malloc (sizeof (Elf_Data) + size);
+ if (unlikely (zdata == NULL))
+ break;
+
+ zdata->d_buf = &zdata[1];
+ zdata->d_type = ELF_T_BYTE;
+ zdata->d_version = EV_CURRENT;
+ zdata->d_size = size;
+ zdata->d_off = 0;
+ zdata->d_align = 1;
+
+ z_stream z =
+ {
+ .next_in = data->d_buf + 4 + 8,
+ .avail_in = data->d_size - 4 - 8,
+ .next_out = zdata->d_buf,
+ .avail_out = zdata->d_size
+ };
+ int zrc = inflateInit (&z);
+ while (z.avail_in > 0 && likely (zrc == Z_OK))
+ {
+ z.next_out = zdata->d_buf + (zdata->d_size - z.avail_out);
+ zrc = inflate (&z, Z_FINISH);
+ if (unlikely (zrc != Z_STREAM_END))
+ {
+ zrc = Z_DATA_ERROR;
+ break;
+ }
+ zrc = inflateReset (&z);
+ }
+ if (likely (zrc == Z_OK))
+ zrc = inflateEnd (&z);
+
+ if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0))
+ free (zdata);
+ else
+ {
+ result->sectiondata[cnt] = zdata;
+ result->sectiondata_gzip_mask |= 1U << cnt;
+ }
+ }
+
+ break;
+ }
+#endif
+
+ return result;
+}
+
+
+/* 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.
+
+ XXX Which sections are absolutely necessary? Add tests if
+ necessary. For now we require only .debug_info. Hopefully this
+ is correct. */
+ if (likely (result != NULL)
+ && unlikely (result->sectiondata[IDX_debug_info] == NULL))
+ {
+ __libdw_free_zdata (result);
+ Dwarf_Sig8_Hash_free (&result->sig8_hash);
+ __libdw_seterrno (DWARF_E_NO_DWARF);
+ free (result);
+ result = NULL;
+ }
+
+ if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
+ {
+ result->fake_loc_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
+ if (unlikely (result->fake_loc_cu == NULL))
+ {
+ __libdw_free_zdata (result);
+ Dwarf_Sig8_Hash_free (&result->sig8_hash);
+ __libdw_seterrno (DWARF_E_NOMEM);
+ free (result);
+ result = NULL;
+ }
+ else
+ {
+ 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);
+ }
+ }
+
+ return result;
+}
+
+
+static Dwarf *
+global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
+{
+ Elf_Scn *scn = NULL;
+
+ while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
+ result = check_section (result, ehdr, scn, false);
+
+ return valid_p (result);
+}
+
+
+static Dwarf *
+scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
+{
+ /* 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! */
+ __libdw_free_zdata (result);
+ 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. */
+ __libdw_free_zdata (result);
+ Dwarf_Sig8_Hash_free (&result->sig8_hash);
+ __libdw_seterrno (DWARF_E_INVALID_ELF);
+ free (result);
+ return NULL;
+ }
+
+ result = check_section (result, ehdr, scn, true);
+ if (result == NULL)
+ break;
+ }
+
+ return valid_p (result);
+}
+
+
+Dwarf *
+dwarf_begin_elf (elf, cmd, scngrp)
+ 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 *);
+
+ /* Allocate the data structure. */
+ Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
+ 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;
+
+ /* Initialize the memory handling. */
+ result->mem_default_size = mem_default_size;
+ result->oom_handler = __libdw_oom;
+ result->mem_tail = (struct libdw_memblock *) (result + 1);
+ result->mem_tail->size = (result->mem_default_size
+ - offsetof (struct libdw_memblock, mem));
+ result->mem_tail->remaining = result->mem_tail->size;
+ result->mem_tail->prev = NULL;
+
+ if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
+ {
+ /* If the caller provides a section group we get the DWARF
+ sections only from this setion 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, ehdr);
+ else
+ return scngrp_read (result, elf, ehdr, 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/3rdparty/elfutils/libdw/dwarf_bitoffset.c b/3rdparty/elfutils/libdw/dwarf_bitoffset.c
new file mode 100644
index 0000000..1648ecd
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_bitoffset.c
@@ -0,0 +1,50 @@
+/* Return bit offset attribute of DIE.
+ Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_bitoffset (die)
+ 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/3rdparty/elfutils/libdw/dwarf_bitsize.c b/3rdparty/elfutils/libdw/dwarf_bitsize.c
new file mode 100644
index 0000000..ea9946b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_bitsize.c
@@ -0,0 +1,50 @@
+/* Return bit size attribute of DIE.
+ Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_bitsize (die)
+ 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/3rdparty/elfutils/libdw/dwarf_bytesize.c b/3rdparty/elfutils/libdw/dwarf_bytesize.c
new file mode 100644
index 0000000..6499a0a
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_bytesize.c
@@ -0,0 +1,50 @@
+/* Return byte size attribute of DIE.
+ Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_bytesize (die)
+ 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/3rdparty/elfutils/libdw/dwarf_cfi_addrframe.c b/3rdparty/elfutils/libdw/dwarf_cfi_addrframe.c
new file mode 100644
index 0000000..1c0da03
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_cfi_addrframe.c
@@ -0,0 +1,57 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+
+int
+dwarf_cfi_addrframe (cache, address, frame)
+ 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/3rdparty/elfutils/libdw/dwarf_cfi_end.c b/3rdparty/elfutils/libdw/dwarf_cfi_end.c
new file mode 100644
index 0000000..6eb2ade
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_cfi_end.c
@@ -0,0 +1,49 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include "cfi.h"
+#include <stdlib.h>
+
+int
+dwarf_cfi_end (cache)
+ Dwarf_CFI *cache;
+{
+ if (cache != NULL)
+ {
+ __libdw_destroy_frame_cache (cache);
+ free (cache);
+ }
+
+ return 0;
+}
+INTDEF (dwarf_cfi_end)
diff --git a/3rdparty/elfutils/libdw/dwarf_child.c b/3rdparty/elfutils/libdw/dwarf_child.c
new file mode 100644
index 0000000..58a438b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_child.c
@@ -0,0 +1,176 @@
+/* Return child of current DIE.
+ Copyright (C) 2003-2011, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <string.h>
+
+/* 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)
+{
+ Dwarf *dbg = die->cu->dbg;
+ const unsigned char *readp;
+
+ /* Find the abbreviation entry. */
+ Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp);
+ if (unlikely (abbrevp == DWARF_END_ABBREV))
+ {
+ invalid_dwarf:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return NULL;
+ }
+
+ /* Search the name attribute. */
+ unsigned char *const endp
+ = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
+ + dbg->sectiondata[IDX_debug_abbrev]->d_size);
+
+ const unsigned char *attrp = abbrevp->attrp;
+ while (1)
+ {
+ /* Get attribute name and form. */
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+ unsigned int attr_name;
+ get_uleb128 (attr_name, attrp, endp);
+
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+ unsigned int attr_form;
+ get_uleb128 (attr_form, attrp, endp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* 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;
+
+ 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;
+ }
+ }
+
+ // XXX Do we need other values?
+ if (codep != NULL)
+ *codep = INVALID;
+ if (formp != NULL)
+ *formp = INVALID;
+
+ return (unsigned char *) readp;
+}
+
+
+int
+dwarf_child (die, result)
+ 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/3rdparty/elfutils/libdw/dwarf_cu_die.c b/3rdparty/elfutils/libdw/dwarf_cu_die.c
new file mode 100644
index 0000000..48f4176
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_cu_die.c
@@ -0,0 +1,68 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include "libdwP.h"
+
+
+Dwarf_Die *
+dwarf_cu_die (cu, result, versionp, abbrev_offsetp, address_sizep,
+ offset_sizep, type_signaturep, type_offsetp)
+ 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;
+{
+ 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 (type_signaturep != NULL)
+ *type_signaturep = cu->type_sig8;
+ if (type_offsetp != NULL)
+ *type_offsetp = cu->type_offset;
+
+ return result;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_cu_getdwarf.c b/3rdparty/elfutils/libdw/dwarf_cu_getdwarf.c
new file mode 100644
index 0000000..f8a2e9b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_cu_getdwarf.c
@@ -0,0 +1,47 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libdwP.h"
+
+
+Dwarf *
+dwarf_cu_getdwarf (cu)
+ Dwarf_CU *cu;
+{
+ if (cu == NULL)
+ /* Some error occurred before. */
+ return NULL;
+
+ return cu->dbg;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_cuoffset.c b/3rdparty/elfutils/libdw/dwarf_cuoffset.c
new file mode 100644
index 0000000..3ceffdb
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_cuoffset.c
@@ -0,0 +1,45 @@
+/* Return offset of DIE in CU.
+ Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Off
+dwarf_cuoffset (die)
+ Dwarf_Die *die;
+{
+ return (die == NULL
+ ? (Dwarf_Off) -1l
+ : (Dwarf_Off) (die->addr - die->cu->startp));
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_decl_column.c b/3rdparty/elfutils/libdw/dwarf_decl_column.c
new file mode 100644
index 0000000..08d36b8
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#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/3rdparty/elfutils/libdw/dwarf_decl_file.c b/3rdparty/elfutils/libdw/dwarf_decl_file.c
new file mode 100644
index 0000000..5657132
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#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 = die->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/3rdparty/elfutils/libdw/dwarf_decl_line.c b/3rdparty/elfutils/libdw/dwarf_decl_line.c
new file mode 100644
index 0000000..80fae6c
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <limits.h>
+#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/3rdparty/elfutils/libdw/dwarf_diecu.c b/3rdparty/elfutils/libdw/dwarf_diecu.c
new file mode 100644
index 0000000..bd9a37a
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_diecu.c
@@ -0,0 +1,55 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+
+
+Dwarf_Die *
+dwarf_diecu (die, result, address_sizep, offset_sizep)
+ 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/3rdparty/elfutils/libdw/dwarf_diename.c b/3rdparty/elfutils/libdw/dwarf_diename.c
new file mode 100644
index 0000000..050d8f1
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_diename.c
@@ -0,0 +1,48 @@
+/* Return string in name attribute of DIE.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_diename (die)
+ 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/3rdparty/elfutils/libdw/dwarf_dieoffset.c b/3rdparty/elfutils/libdw/dwarf_dieoffset.c
new file mode 100644
index 0000000..965b2c8
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_dieoffset.c
@@ -0,0 +1,46 @@
+/* Return offset of DIE.
+ Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Off
+dwarf_dieoffset (die)
+ Dwarf_Die *die;
+{
+ return (die == NULL
+ ? ~0ul
+ : (Dwarf_Off) (die->addr - die->cu->startp + die->cu->start));
+}
+INTDEF(dwarf_dieoffset)
diff --git a/3rdparty/elfutils/libdw/dwarf_end.c b/3rdparty/elfutils/libdw/dwarf_end.c
new file mode 100644
index 0000000..922dc8f
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_end.c
@@ -0,0 +1,129 @@
+/* Release debugging handling context.
+ Copyright (C) 2002-2011, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <search.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#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;
+
+ Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
+
+ tdestroy (p->locs, noop_free);
+}
+
+
+#if USE_ZLIB
+void
+internal_function
+__libdw_free_zdata (Dwarf *dwarf)
+{
+ unsigned int gzip_mask = dwarf->sectiondata_gzip_mask;
+ while (gzip_mask != 0)
+ {
+ int i = ffs (gzip_mask);
+ assert (i > 0);
+ --i;
+ assert (i < IDX_last);
+ free (dwarf->sectiondata[i]);
+ gzip_mask &= ~(1U << i);
+ }
+}
+#endif
+
+int
+dwarf_end (dwarf)
+ 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);
+
+ struct libdw_memblock *memp = dwarf->mem_tail;
+ /* The first block is allocated together with the Dwarf object. */
+ while (memp->prev != NULL)
+ {
+ struct libdw_memblock *prevp = memp->prev;
+ free (memp);
+ memp = prevp;
+ }
+
+ /* Free the pubnames helper structure. */
+ free (dwarf->pubnames_sets);
+
+ __libdw_free_zdata (dwarf);
+
+ /* Free the ELF descriptor if necessary. */
+ if (dwarf->free_elf)
+ elf_end (dwarf->elf);
+
+ /* Free the fake location list CU. */
+ free (dwarf->fake_loc_cu);
+
+ /* Free the context descriptor. */
+ free (dwarf);
+ }
+
+ return 0;
+}
+INTDEF(dwarf_end)
diff --git a/3rdparty/elfutils/libdw/dwarf_entry_breakpoints.c b/3rdparty/elfutils/libdw/dwarf_entry_breakpoints.c
new file mode 100644
index 0000000..ffd5169
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_entry_breakpoints.c
@@ -0,0 +1,157 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "libdwP.h"
+#include <dwarf.h>
+#include <stdlib.h>
+
+
+int
+dwarf_entry_breakpoints (die, bkpts)
+ Dwarf_Die *die;
+ Dwarf_Addr **bkpts;
+{
+ int nbkpts = 0;
+ *bkpts = NULL;
+
+ /* Add one breakpoint location to the result vector. */
+ inline int add_bkpt (Dwarf_Addr pc)
+ {
+ Dwarf_Addr *newlist = realloc (*bkpts, ++nbkpts * sizeof newlist[0]);
+ if (newlist == NULL)
+ {
+ free (*bkpts);
+ *bkpts = NULL;
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return -1;
+ }
+ newlist[nbkpts - 1] = pc;
+ *bkpts = newlist;
+ return nbkpts;
+ }
+
+ /* Fallback result, break at the entrypc/lowpc value. */
+ inline int entrypc_bkpt (void)
+ {
+ Dwarf_Addr pc;
+ return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc);
+ }
+
+ /* 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 ();
+ __libdw_seterrno (error);
+ return -1;
+ }
+
+ /* 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. */
+ inline int search_range (Dwarf_Addr low, Dwarf_Addr high,
+ bool dwarf, bool adhoc)
+ {
+ 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) < 0)
+ return -1;
+ if (adhoc && nbkpts == 0)
+ while (++l < nlines && lines->info[l].addr < high)
+ if (!lines->info[l].end_sequence)
+ return add_bkpt (lines->info[l].addr);
+ return nbkpts;
+ }
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ 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) ?: entrypc_bkpt ();
+
+ 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) < 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))
+ ?: entrypc_bkpt ());
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_entrypc.c b/3rdparty/elfutils/libdw/dwarf_entrypc.c
new file mode 100644
index 0000000..8eb39db
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_entrypc.c
@@ -0,0 +1,50 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_entrypc (die, return_addr)
+ 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/3rdparty/elfutils/libdw/dwarf_error.c b/3rdparty/elfutils/libdw/dwarf_error.c
new file mode 100644
index 0000000..08b691a
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_error.c
@@ -0,0 +1,122 @@
+/* Retrieve ELF descriptor used for DWARF access.
+ Copyright (C) 2002, 2003, 2004, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+
+#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_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_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_LOCLIST] = N_("no 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_INVALID_CFI] = N_("invalid CFI section"),
+ [DWARF_E_NO_ALT_DEBUGLINK] = N_("no alternative debug link found"),
+ [DWARF_E_INVALID_OPCODE] = N_("invalid opcode"),
+ };
+#define nerrmsgs (sizeof (errmsgs) / sizeof (errmsgs[0]))
+
+
+void
+__libdw_seterrno (value)
+ int value;
+{
+ global_error = (value >= 0 && value < (int) nerrmsgs
+ ? value : DWARF_E_UNKNOWN_ERROR);
+}
+
+
+const char *
+dwarf_errmsg (error)
+ 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/3rdparty/elfutils/libdw/dwarf_filesrc.c b/3rdparty/elfutils/libdw/dwarf_filesrc.c
new file mode 100644
index 0000000..d866ce7
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_formaddr.c b/3rdparty/elfutils/libdw/dwarf_formaddr.c
new file mode 100644
index 0000000..9d4a388
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formaddr.c
@@ -0,0 +1,59 @@
+/* Return address represented by attribute.
+ Copyright (C) 2003-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formaddr (attr, return_addr)
+ Dwarf_Attribute *attr;
+ Dwarf_Addr *return_addr;
+{
+ if (attr == NULL)
+ return -1;
+
+ if (unlikely (attr->form != DW_FORM_addr))
+ {
+ __libdw_seterrno (DWARF_E_NO_ADDR);
+ return -1;
+ }
+
+ if (__libdw_read_address (attr->cu->dbg,
+ cu_sec_idx (attr->cu), attr->valp,
+ attr->cu->address_size, return_addr))
+ return -1;
+
+ return 0;
+}
+INTDEF(dwarf_formaddr)
diff --git a/3rdparty/elfutils/libdw/dwarf_formblock.c b/3rdparty/elfutils/libdw/dwarf_formblock.c
new file mode 100644
index 0000000..3d56f22
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formblock.c
@@ -0,0 +1,95 @@
+/* Return block represented by attribute.
+ Copyright (C) 2004-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formblock (attr, return_block)
+ 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;
+
+ 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/3rdparty/elfutils/libdw/dwarf_formflag.c b/3rdparty/elfutils/libdw/dwarf_formflag.c
new file mode 100644
index 0000000..bdc2267
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formflag.c
@@ -0,0 +1,61 @@
+/* Return flag represented by attribute.
+ Copyright (C) 2004-2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formflag (attr, return_bool)
+ 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/3rdparty/elfutils/libdw/dwarf_formref.c b/3rdparty/elfutils/libdw/dwarf_formref.c
new file mode 100644
index 0000000..2592437
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formref.c
@@ -0,0 +1,113 @@
+/* Return reference offset represented by attribute.
+ Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+int
+__libdw_formref (attr, return_offset)
+ 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:
+ /* 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 (attr, return_offset)
+ Dwarf_Attribute *attr;
+ Dwarf_Off *return_offset;
+{
+ if (attr == NULL)
+ return -1;
+
+ return __libdw_formref (attr, return_offset);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_formref_die.c b/3rdparty/elfutils/libdw/dwarf_formref_die.c
new file mode 100644
index 0000000..63f6697
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formref_die.c
@@ -0,0 +1,121 @@
+/* Look up the DIE in a reference-form attribute.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+Dwarf_Die *
+dwarf_formref_die (attr, result)
+ 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)
+ {
+ /* This has an absolute offset. */
+
+ uint8_t ref_size = (cu->version == 2 && attr->form == DW_FORM_ref_addr
+ ? cu->address_size
+ : cu->offset_size);
+
+ Dwarf *dbg_ret = (attr->form == DW_FORM_GNU_ref_alt
+ ? cu->dbg->alt_dwarf : 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 .debug_types type unit headers. */
+
+ uint64_t sig = read_8ubyte_unaligned (cu->dbg, attr->valp);
+ cu = Dwarf_Sig8_Hash_find (&cu->dbg->sig8_hash, sig, NULL);
+ if (cu == NULL)
+ /* Not seen before. We have to scan through the type units. */
+ do
+ {
+ cu = __libdw_intern_next_unit (attr->cu->dbg, true);
+ if (cu == NULL)
+ {
+ __libdw_seterrno (INTUSE(dwarf_errno) ()
+ ?: DWARF_E_INVALID_REFERENCE);
+ return NULL;
+ }
+ }
+ while (cu->type_sig8 != sig);
+
+ datap = cu->dbg->sectiondata[IDX_debug_types]->d_buf;
+ size = cu->dbg->sectiondata[IDX_debug_types]->d_size;
+ offset = cu->type_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/3rdparty/elfutils/libdw/dwarf_formsdata.c b/3rdparty/elfutils/libdw/dwarf_formsdata.c
new file mode 100644
index 0000000..2380bf4
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formsdata.c
@@ -0,0 +1,98 @@
+/* Return signed constant represented by attribute.
+ Copyright (C) 2003, 2005, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formsdata (attr, return_sval)
+ 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 = *attr->valp;
+ break;
+
+ case DW_FORM_data2:
+ if (datap + 2 > endp)
+ goto invalid;
+ *return_sval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_data4:
+ if (datap + 4 > endp)
+ goto invalid;
+ *return_sval = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_data8:
+ if (datap + 8 > endp)
+ goto invalid;
+ *return_sval = read_8ubyte_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;
+
+ default:
+ __libdw_seterrno (DWARF_E_NO_CONSTANT);
+ return -1;
+ }
+
+ return 0;
+}
+INTDEF(dwarf_formsdata)
diff --git a/3rdparty/elfutils/libdw/dwarf_formstring.c b/3rdparty/elfutils/libdw/dwarf_formstring.c
new file mode 100644
index 0000000..02b56d4
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formstring.c
@@ -0,0 +1,76 @@
+/* Return string associated with given attribute.
+ Copyright (C) 2003-2010, 2013 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_formstring (attrp)
+ 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 *dbg = attrp->cu->dbg;
+ Dwarf *dbg_ret = attrp->form == DW_FORM_GNU_strp_alt ? dbg->alt_dwarf : dbg;
+
+ if (unlikely (dbg_ret == NULL))
+ {
+ __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK);
+ return NULL;
+ }
+
+
+ if (unlikely (attrp->form != DW_FORM_strp
+ && attrp->form != DW_FORM_GNU_strp_alt)
+ || dbg_ret->sectiondata[IDX_debug_str] == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NO_STRING);
+ return NULL;
+ }
+
+ uint64_t off;
+ if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (attrp->cu), attrp->valp,
+ attrp->cu->offset_size, &off, IDX_debug_str, 1))
+ return NULL;
+
+ return (const char *) dbg_ret->sectiondata[IDX_debug_str]->d_buf + off;
+}
+INTDEF(dwarf_formstring)
diff --git a/3rdparty/elfutils/libdw/dwarf_formudata.c b/3rdparty/elfutils/libdw/dwarf_formudata.c
new file mode 100644
index 0000000..a01ff31
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_formudata.c
@@ -0,0 +1,233 @@
+/* Return unsigned constant represented by attribute.
+ Copyright (C) 2003-2012, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+internal_function unsigned char *
+__libdw_formptr (Dwarf_Attribute *attr, int sec_index,
+ int err_nodata, unsigned char **endpp,
+ Dwarf_Off *offsetp)
+{
+ if (attr == NULL)
+ return NULL;
+
+ const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
+ if (unlikely (d == NULL))
+ {
+ __libdw_seterrno (err_nodata);
+ return NULL;
+ }
+
+ Dwarf_Word offset;
+ if (attr->form == DW_FORM_sec_offset)
+ {
+ 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 (attr, return_uval)
+ 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:
+ /* loclistptr */
+ if (__libdw_formptr (attr, IDX_debug_loc,
+ DWARF_E_NO_LOCLIST, 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:
+ /* 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:
+ /* rangelistptr */
+ if (__libdw_formptr (attr, IDX_debug_ranges,
+ DWARF_E_NO_DEBUG_RANGES, 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;
+
+ 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:
+ if (datap + 1 > endp)
+ goto invalid;
+ get_uleb128 (*return_uval, datap, endp);
+ break;
+
+ default:
+ __libdw_seterrno (DWARF_E_NO_CONSTANT);
+ return -1;
+ }
+
+ return 0;
+}
+INTDEF(dwarf_formudata)
diff --git a/3rdparty/elfutils/libdw/dwarf_frame_cfa.c b/3rdparty/elfutils/libdw/dwarf_frame_cfa.c
new file mode 100644
index 0000000..a9ae7e7
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_frame_cfa.c
@@ -0,0 +1,80 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <dwarf.h>
+#include <stdlib.h>
+
+int
+dwarf_frame_cfa (fs, ops, nops)
+ 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/3rdparty/elfutils/libdw/dwarf_frame_info.c b/3rdparty/elfutils/libdw/dwarf_frame_info.c
new file mode 100644
index 0000000..7da46fb
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_frame_info.c
@@ -0,0 +1,53 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+
+int
+dwarf_frame_info (fs, start, end, signalp)
+ 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/3rdparty/elfutils/libdw/dwarf_frame_register.c b/3rdparty/elfutils/libdw/dwarf_frame_register.c
new file mode 100644
index 0000000..10d2fe4
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_frame_register.c
@@ -0,0 +1,123 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <dwarf.h>
+
+int
+dwarf_frame_register (fs, regno, ops_mem, ops, nops)
+ 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/3rdparty/elfutils/libdw/dwarf_func_inline.c b/3rdparty/elfutils/libdw/dwarf_func_inline.c
new file mode 100644
index 0000000..bc9db1c
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_func_inline.c
@@ -0,0 +1,101 @@
+/* Convenience functions for handling DWARF descriptions of inline 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+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, &scope_visitor, NULL, &v);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getabbrev.c b/3rdparty/elfutils/libdw/dwarf_getabbrev.c
new file mode 100644
index 0000000..0efde45
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getabbrev.c
@@ -0,0 +1,165 @@
+/* Get abbreviation at given offset.
+ Copyright (C) 2003, 2004, 2005, 2006, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Abbrev *
+internal_function
+__libdw_getabbrev (dbg, cu, offset, lengthp, result)
+ 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)) == 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:
+ __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 count them while doing so. */
+ abb->attrcnt = 0;
+ 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);
+ }
+ while (attrname != 0 && attrform != 0 && ++abb->attrcnt);
+
+ /* 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)
+ (void) Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb);
+
+ out:
+ return abb;
+}
+
+
+Dwarf_Abbrev *
+dwarf_getabbrev (die, offset, lengthp)
+ Dwarf_Die *die;
+ Dwarf_Off offset;
+ size_t *lengthp;
+{
+ return __libdw_getabbrev (die->cu->dbg, die->cu,
+ die->cu->orig_abbrev_offset + offset, lengthp,
+ NULL);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getabbrevattr.c b/3rdparty/elfutils/libdw/dwarf_getabbrevattr.c
new file mode 100644
index 0000000..574467c
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getabbrevattr.c
@@ -0,0 +1,80 @@
+/* Get specific attribute of abbreviation.
+ Copyright (C) 2003, 2004, 2005, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_getabbrevattr (abbrev, idx, namep, formp, offsetp)
+ Dwarf_Abbrev *abbrev;
+ size_t idx;
+ unsigned int *namep;
+ unsigned int *formp;
+ 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;
+
+ do
+ {
+ start_attrp = attrp;
+
+ /* Attribute code and form are encoded as ULEB128 values.i
+ XXX We have no way to bounds check. */
+ get_uleb128 (name, attrp, attrp + len_leb128 (name));
+ get_uleb128 (form, attrp, attrp + len_leb128 (form));
+
+ /* 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 (offsetp != NULL)
+ *offsetp = (start_attrp - abbrev->attrp) + abbrev->offset;
+
+ return 0;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getabbrevcode.c b/3rdparty/elfutils/libdw/dwarf_getabbrevcode.c
new file mode 100644
index 0000000..0df9064
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getabbrevcode.c
@@ -0,0 +1,44 @@
+/* Get abbreviation code.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_getabbrevcode (abbrev)
+ Dwarf_Abbrev *abbrev;
+{
+ return abbrev == NULL ? 0 : abbrev->code;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getabbrevtag.c b/3rdparty/elfutils/libdw/dwarf_getabbrevtag.c
new file mode 100644
index 0000000..36a5262
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getabbrevtag.c
@@ -0,0 +1,44 @@
+/* Get abbreviation tag.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_getabbrevtag (abbrev)
+ Dwarf_Abbrev *abbrev;
+{
+ return abbrev == NULL ? 0 : abbrev->tag;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getalt.c b/3rdparty/elfutils/libdw/dwarf_getalt.c
new file mode 100644
index 0000000..cc434f0
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getalt.c
@@ -0,0 +1,42 @@
+/* Retrieves the DWARF descriptor for debugaltlink data.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+Dwarf *
+dwarf_getalt (Dwarf *main)
+{
+ if (main == NULL)
+ return NULL;
+ return main->alt_dwarf;
+}
+INTDEF (dwarf_getalt)
diff --git a/3rdparty/elfutils/libdw/dwarf_getarange_addr.c b/3rdparty/elfutils/libdw/dwarf_getarange_addr.c
new file mode 100644
index 0000000..fc143de
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getarange_addr.c
@@ -0,0 +1,62 @@
+/* Get address range which includes given address.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwP.h>
+
+
+Dwarf_Arange *
+dwarf_getarange_addr (aranges, 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/3rdparty/elfutils/libdw/dwarf_getarangeinfo.c b/3rdparty/elfutils/libdw/dwarf_getarangeinfo.c
new file mode 100644
index 0000000..67b6e67
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwP.h>
+
+
+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/3rdparty/elfutils/libdw/dwarf_getaranges.c b/3rdparty/elfutils/libdw/dwarf_getaranges.c
new file mode 100644
index 0000000..4953af5
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getaranges.c
@@ -0,0 +1,265 @@
+/* Return list address ranges.
+ Copyright (C) 2000-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+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 (dbg, aranges, naranges)
+ 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. */
+ Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
+ unsigned int length_bytes = 4;
+ if (length == DWARF3_LENGTH_64_BIT)
+ {
+ 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;
+
+ 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;
+ if (__libdw_read_offset_inc (dbg,
+ IDX_debug_aranges, &readp,
+ length_bytes, &offset, IDX_debug_info, 4))
+ goto fail;
+
+ unsigned int address_size = *readp++;
+ if (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 (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. */
+ const char *cu_header = (dbg->sectiondata[IDX_debug_info]->d_buf
+ + offset);
+ unsigned int offset_size;
+ if (read_4ubyte_unaligned_noncvt (cu_header) == DWARF3_LENGTH_64_BIT)
+ offset_size = 8;
+ else
+ offset_size = 4;
+ new_arange->arange.offset = DIE_OFFSET_FROM_CU_OFFSET (offset,
+ offset_size,
+ false);
+
+ 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/3rdparty/elfutils/libdw/dwarf_getattrcnt.c b/3rdparty/elfutils/libdw/dwarf_getattrcnt.c
new file mode 100644
index 0000000..72be766
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getattrcnt.c
@@ -0,0 +1,48 @@
+/* Get number of attributes of abbreviation.
+ Copyright (C) 2003, 2004 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_getattrcnt (abbrev, attrcntp)
+ Dwarf_Abbrev *abbrev;
+ size_t *attrcntp;
+{
+ if (abbrev == NULL)
+ return -1;
+
+ *attrcntp = abbrev->attrcnt;
+
+ return 0;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getattrs.c b/3rdparty/elfutils/libdw/dwarf_getattrs.c
new file mode 100644
index 0000000..0da8b5b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getattrs.c
@@ -0,0 +1,120 @@
+/* Get attributes of the DIE.
+ Copyright (C) 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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;
+
+ /* Find the abbreviation entry. */
+ Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &die_addr);
+
+ if (unlikely (abbrevp == DWARF_END_ABBREV))
+ {
+ invalid_dwarf:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1l;
+ }
+
+ /* 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. */
+ Dwarf *dbg = die->cu->dbg;
+ const unsigned char *endp;
+ endp = ((const unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
+ + dbg->sectiondata[IDX_debug_abbrev]->d_size);
+ while (1)
+ {
+ /* Are we still in bounds? */
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+
+ /* Get attribute name and form. */
+ Dwarf_Attribute attr;
+ const unsigned char *remembered_attrp = attrp;
+
+ get_uleb128 (attr.code, attrp, endp);
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+ get_uleb128 (attr.form, attrp, endp);
+
+ /* 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 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. */
+ 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;
+ }
+ }
+ /* NOTREACHED */
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getcfi.c b/3rdparty/elfutils/libdw/dwarf_getcfi.c
new file mode 100644
index 0000000..a49a9f0
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getcfi.c
@@ -0,0 +1,73 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include "cfi.h"
+#include <dwarf.h>
+
+Dwarf_CFI *
+dwarf_getcfi (dbg)
+ 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);
+ cfi->other_byte_order = dbg->other_byte_order;
+
+ 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/3rdparty/elfutils/libdw/dwarf_getcfi_elf.c b/3rdparty/elfutils/libdw/dwarf_getcfi_elf.c
new file mode 100644
index 0000000..61ca60d
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getcfi_elf.c
@@ -0,0 +1,320 @@
+/* Get CFI from ELF file's exception-handling info.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "libdwP.h"
+#include "cfi.h"
+#include "encoded-value.h"
+#include <dwarf.h>
+
+
+static Dwarf_CFI *
+allocate_cfi (Elf *elf, 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;
+ }
+
+ 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 (*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)
+{
+ if (unlikely (phdr->p_filesz < 4))
+ goto invalid;
+
+ Elf_Data *data = elf_getdata_rawchunk (elf, phdr->p_offset, phdr->p_filesz,
+ ELF_T_BYTE);
+ if (data == NULL)
+ {
+ invalid_hdr:
+ invalid:
+ /* XXX might be read error or corrupt phdr */
+ __libdw_seterrno (DWARF_E_INVALID_CFI);
+ return NULL;
+ }
+
+ 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);
+ if (search_table == (void *) -1l)
+ 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, eh_frame_ptr);
+ if (cfi != NULL)
+ {
+ cfi->data = (Elf_Data_Scn *) data;
+
+ if (search_table != NULL)
+ {
+ cfi->search_table = search_table;
+ 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)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_ELF);
+ return NULL;
+ }
+ Dwarf_CFI *cfi = allocate_cfi (elf, 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)
+ {
+ 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);
+ if (cfi->search_table == (void *) -1l)
+ {
+ 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_PROGBITS)
+ 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 *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/3rdparty/elfutils/libdw/dwarf_getelf.c b/3rdparty/elfutils/libdw/dwarf_getelf.c
new file mode 100644
index 0000000..ecd1859
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getelf.c
@@ -0,0 +1,48 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libdwP.h"
+
+
+Elf *
+dwarf_getelf (dwarf)
+ Dwarf *dwarf;
+{
+ if (dwarf == NULL)
+ /* Some error occurred before. */
+ return NULL;
+
+ return dwarf->elf;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getfuncs.c b/3rdparty/elfutils/libdw/dwarf_getfuncs.c
new file mode 100644
index 0000000..f79b0a7
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getfuncs.c
@@ -0,0 +1,118 @@
+/* Get function information.
+ Copyright (C) 2005, 2013 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#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, &tree_visitor, NULL, &v);
+
+ if (res == DWARF_CB_ABORT)
+ return (ptrdiff_t) v.last_addr;
+ else
+ return res;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getlocation.c b/3rdparty/elfutils/libdw/dwarf_getlocation.c
new file mode 100644
index 0000000..068f385
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getlocation.c
@@ -0,0 +1,853 @@
+/* Return location expression list.
+ Copyright (C) 2000-2010, 2013, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <search.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <libdwP.h>
+
+
+static bool
+attr_ok (Dwarf_Attribute *attr)
+{
+ if (attr == NULL)
+ return false;
+
+ /* Must be one of the attributes listed below. */
+ switch (attr->code)
+ {
+ case DW_AT_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_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_LOCLIST);
+ 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. */
+static void
+store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op)
+{
+ 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;
+ // Ignored, equal to op->number. And data length already checked.
+ (void) __libdw_get_uleb128 (&data, data + len_leb128 (Dwarf_Word));
+ block->addr = op;
+ block->data = (unsigned char *) data;
+ block->length = op->number;
+ (void) tsearch (block, cache, loc_compare);
+}
+
+int
+dwarf_getlocation_implicit_value (attr, op, return_block)
+ 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;
+}
+
+/* DW_AT_data_member_location can be a constant as well as a loclistptr.
+ Only data[48] indicate a loclistptr. */
+static int
+check_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;
+
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ 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;
+
+ if (cfap)
+ {
+ /* Synthesize the operation to push the CFA before the expression. */
+ struct loclist *newloc;
+ newloc = (struct loclist *) alloca (sizeof (struct loclist));
+ newloc->atom = DW_OP_call_frame_cfa;
+ newloc->number = 0;
+ newloc->number2 = 0;
+ newloc->offset = -1;
+ newloc->next = loclist;
+ loclist = newloc;
+ ++n;
+ }
+
+ /* Decode the opcodes. It is possible in some situations to have a
+ block of size zero. */
+ while (data < end_data)
+ {
+ struct loclist *newloc;
+ newloc = (struct loclist *) alloca (sizeof (struct loclist));
+ newloc->number = 0;
+ newloc->number2 = 0;
+ newloc->offset = data - block->data;
+ newloc->next = loclist;
+ loclist = newloc;
+ ++n;
+
+ switch ((newloc->atom = *data++))
+ {
+ case DW_OP_addr:
+ /* Address, depends on address size of CU. */
+ if (__libdw_read_address_inc (dbg, sec_index, &data,
+ address_size, &newloc->number))
+ return -1;
+ break;
+
+ case DW_OP_call_ref:
+ /* DW_FORM_ref_addr, depends on offset size of CU. */
+ if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
+ &newloc->number, IDX_debug_info, 0))
+ return -1;
+ 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);
+ 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_GNU_convert:
+ case DW_OP_GNU_reinterpret:
+ 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_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_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_GNU_implicit_pointer:
+ /* DW_FORM_ref_addr, depends on offset size of CU. */
+ if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
+ &newloc->number, IDX_debug_info, 0))
+ return -1;
+ if (unlikely (data >= end_data))
+ goto invalid;
+ get_uleb128 (newloc->number2, data, end_data); /* Byte offset. */
+ break;
+
+ case DW_OP_GNU_deref_type:
+ if (unlikely (data + 1 >= end_data))
+ goto invalid;
+ newloc->number = *data++;
+ get_uleb128 (newloc->number2, data, end_data);
+ break;
+
+ 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;
+ newloc = (struct loclist *) alloca (sizeof (struct loclist));
+ newloc->atom = DW_OP_stack_value;
+ newloc->number = 0;
+ newloc->number2 = 0;
+ newloc->offset = data - block->data;
+ newloc->next = loclist;
+ loclist = newloc;
+ ++n;
+ }
+
+ /* 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);
+ return -1;
+ }
+ }
+
+ /* 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)
+ store_implicit_value (dbg, cache, &result[n]);
+
+ loclist = loclist->next;
+ }
+ 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 (attr, llbuf, listlen)
+ Dwarf_Attribute *attr;
+ Dwarf_Op **llbuf;
+ size_t *listlen;
+{
+ if (! attr_ok (attr))
+ return -1;
+
+ int result = check_constant_offset (attr, llbuf, listlen);
+ if (result != 1)
+ return result;
+
+ /* If it has a block form, it's a single location expression. */
+ Dwarf_Block block;
+ if (INTUSE(dwarf_formblock) (attr, &block) != 0)
+ return -1;
+
+ return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
+}
+
+static int
+attr_base_address (attr, basep)
+ Dwarf_Attribute *attr;
+ Dwarf_Addr *basep;
+{
+ /* Fetch the CU's base address. */
+ Dwarf_Die cudie = CUDIE (attr->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 (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0)
+ && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
+ DW_AT_entry_pc,
+ &attr_mem),
+ basep) != 0)
+ {
+ if (INTUSE(dwarf_errno) () != 0)
+ return -1;
+
+ /* 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. */
+ *basep = 0;
+ }
+ return 0;
+}
+
+static int
+initial_offset_base (attr, offset, basep)
+ Dwarf_Attribute *attr;
+ ptrdiff_t *offset;
+ Dwarf_Addr *basep;
+{
+ if (attr_base_address (attr, basep) != 0)
+ return -1;
+
+ Dwarf_Word start_offset;
+ if (__libdw_formptr (attr, IDX_debug_loc,
+ DWARF_E_NO_LOCLIST,
+ NULL, &start_offset) == NULL)
+ return -1;
+
+ *offset = start_offset;
+ return 0;
+}
+
+static ptrdiff_t
+getlocations_addr (attr, offset, basep, startp, endp, address,
+ locs, expr, exprlen)
+ Dwarf_Attribute *attr;
+ ptrdiff_t offset;
+ Dwarf_Addr *basep;
+ Dwarf_Addr *startp;
+ Dwarf_Addr *endp;
+ Dwarf_Addr address;
+ Elf_Data *locs;
+ Dwarf_Op **expr;
+ size_t *exprlen;
+{
+ unsigned char *readp = locs->d_buf + offset;
+ unsigned char *readendp = locs->d_buf + locs->d_size;
+
+ next:
+ if (readendp - readp < attr->cu->address_size * 2)
+ {
+ invalid:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+
+ switch (__libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
+ &readp, attr->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;
+ }
+
+ if (readendp - readp < 2)
+ goto invalid;
+
+ /* We have a location expression. */
+ Dwarf_Block block;
+ block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
+ block.data = readp;
+ if (readendp - readp < (ptrdiff_t) block.length)
+ goto invalid;
+ readp += block.length;
+
+ *startp = *basep + begin;
+ *endp = *basep + 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 (attr->cu, &block, expr, exprlen, IDX_debug_loc) != 0)
+ return -1;
+
+ return readp - (unsigned char *) locs->d_buf;
+}
+
+int
+dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
+ 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. */
+ Dwarf_Block block;
+ if (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;
+ }
+
+ int error = INTUSE(dwarf_errno) ();
+ if (unlikely (error != DWARF_E_NO_BLOCK))
+ {
+ __libdw_seterrno (error);
+ return -1;
+ }
+
+ int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
+ 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. */
+ if (initial_offset_base (attr, &off, &base) != 0)
+ return -1;
+
+ const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
+ if (d == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NO_LOCLIST);
+ return -1;
+ }
+
+ 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 (attr, offset, basep, startp, endp, expr, exprlen)
+ 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. */
+ Dwarf_Block block;
+ if (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;
+ }
+
+ int error = INTUSE(dwarf_errno) ();
+ if (unlikely (error != DWARF_E_NO_BLOCK))
+ {
+ __libdw_seterrno (error);
+ return -1;
+ }
+
+ int result = check_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;
+ }
+
+ /* We must be looking at a true loclistptr, fetch the initial
+ base address and offset. */
+ if (initial_offset_base (attr, &offset, basep) != 0)
+ return -1;
+ }
+
+ const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
+ if (d == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NO_LOCLIST);
+ return -1;
+ }
+
+ return getlocations_addr (attr, offset, basep, startp, endp,
+ (Dwarf_Word) -1, d, expr, exprlen);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getlocation_attr.c b/3rdparty/elfutils/libdw/dwarf_getlocation_attr.c
new file mode 100644
index 0000000..3229baf
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getlocation_attr.c
@@ -0,0 +1,122 @@
+/* Return DWARF attribute associated with a location expression op.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <libdwP.h>
+
+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 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->dbg->fake_loc_cu;
+ }
+}
+
+int
+dwarf_getlocation_attr (attr, op, result)
+ 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_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_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_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_GNU_implicit_pointer:
+ {
+ 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/3rdparty/elfutils/libdw/dwarf_getlocation_die.c b/3rdparty/elfutils/libdw/dwarf_getlocation_die.c
new file mode 100644
index 0000000..fa03aac
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getlocation_die.c
@@ -0,0 +1,78 @@
+/* Return DIE associated with a location expression op.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <libdwP.h>
+
+int
+dwarf_getlocation_die (attr, op, result)
+ Dwarf_Attribute *attr;
+ const Dwarf_Op *op;
+ Dwarf_Die *result;
+{
+ if (attr == NULL)
+ return -1;
+
+ Dwarf_Off dieoff;
+ switch (op->atom)
+ {
+ case DW_OP_GNU_implicit_pointer:
+ case DW_OP_call_ref:
+ dieoff = op->number;
+ break;
+
+ case DW_OP_GNU_parameter_ref:
+ case DW_OP_GNU_convert:
+ case DW_OP_GNU_reinterpret:
+ case DW_OP_GNU_const_type:
+ case DW_OP_call2:
+ case DW_OP_call4:
+ dieoff = attr->cu->start + op->number;
+ break;
+
+ case DW_OP_GNU_regval_type:
+ case DW_OP_GNU_deref_type:
+ dieoff = attr->cu->start + op->number2;
+ break;
+
+ default:
+ __libdw_seterrno (DWARF_E_INVALID_ACCESS);
+ return -1;
+ }
+
+ if (__libdw_offdie (attr->cu->dbg, dieoff, result,
+ attr->cu->type_offset != 0) == NULL)
+ return -1;
+
+ return 0;
+}
+INTDEF(dwarf_getlocation_die);
diff --git a/3rdparty/elfutils/libdw/dwarf_getlocation_implicit_pointer.c b/3rdparty/elfutils/libdw/dwarf_getlocation_implicit_pointer.c
new file mode 100644
index 0000000..f1c16be
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getlocation_implicit_pointer.c
@@ -0,0 +1,79 @@
+/* Return associated attribute for DW_OP_GNU_implicit_pointer.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+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 (attr, op, result)
+ Dwarf_Attribute *attr;
+ const Dwarf_Op *op;
+ Dwarf_Attribute *result;
+{
+ if (attr == NULL)
+ return -1;
+
+ if (unlikely (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,
+ attr->cu->type_offset != 0) == 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/3rdparty/elfutils/libdw/dwarf_getmacros.c b/3rdparty/elfutils/libdw/dwarf_getmacros.c
new file mode 100644
index 0000000..f9f2996
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getmacros.c
@@ -0,0 +1,548 @@
+/* Get macro information.
+ Copyright (C) 2002-2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <search.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwP.h>
+
+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)
+ INTUSE(dwarf_formudata) (attr, &line_offset);
+
+ 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)
+ {
+ __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)
+ INTUSE(dwarf_formudata) (attr, &line_offset);
+ }
+
+ /* """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_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_GNU_define - 1] = p_udata_str,
+ [DW_MACRO_GNU_undef - 1] = p_udata_str,
+ [DW_MACRO_GNU_define_indirect - 1] = p_udata_strp,
+ [DW_MACRO_GNU_undef_indirect - 1] = p_udata_strp,
+ [DW_MACRO_GNU_start_file - 1] = p_udata_udata,
+ [DW_MACRO_GNU_end_file - 1] = p_none,
+ [DW_MACRO_GNU_transparent_include - 1] = p_secoffset,
+ /* N.B. DW_MACRO_undef_indirectx, DW_MACRO_define_indirectx
+ should be added when 130313.1 is supported. */
+ };
+
+ 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 arbitrarily pretend it's version 4. */
+ Dwarf_CU fake_cu = {
+ .dbg = dbg,
+ .version = 4,
+ .offset_size = table->is_64bit ? 8 : 4,
+ .startp = (void *) startp + offset,
+ .endp = (void *) endp,
+ };
+
+ Dwarf_Attribute attributes[proto->nforms];
+ 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. */
+ attributes[i].code = DW_AT_GNU_macros;
+ attributes[i].form = proto->forms[i];
+ attributes[i].valp = (void *) readp;
+ attributes[i].cu = &fake_cu;
+
+ size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
+ if (len == (size_t) -1)
+ return -1;
+
+ readp += len;
+ }
+
+ Dwarf_Macro macro = {
+ .table = table,
+ .opcode = opcode,
+ .attributes = attributes,
+ };
+
+ if (callback (&macro, arg) != 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 (cudie, callback, arg, token)
+ 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)
+ 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/3rdparty/elfutils/libdw/dwarf_getpubnames.c b/3rdparty/elfutils/libdw/dwarf_getpubnames.c
new file mode 100644
index 0000000..19f4eae
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getpubnames.c
@@ -0,0 +1,245 @@
+/* Get public symbol information.
+ Copyright (C) 2002, 2003, 2004, 2005, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include <libdwP.h>
+#include <dwarf.h>
+
+
+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)
+ {
+ __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 (dbg, callback, arg, offset)
+ 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/3rdparty/elfutils/libdw/dwarf_getscopes.c b/3rdparty/elfutils/libdw/dwarf_getscopes.c
new file mode 100644
index 0000000..0ca6da0
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getscopes.c
@@ -0,0 +1,201 @@
+/* Return scope DIEs containing PC address.
+ Copyright (C) 2005, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+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)
+ {
+ __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, &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, &pc_match, &pc_record, &a);
+
+ if (result == 0 && a.scopes != NULL)
+ result = __libdw_visit_scopes (0, &cu, &origin_match, NULL, &a);
+
+ if (result > 0)
+ *scopes = a.scopes;
+
+ return result;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getscopes_die.c b/3rdparty/elfutils/libdw/dwarf_getscopes_die.c
new file mode 100644
index 0000000..d361585
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getscopes_die.c
@@ -0,0 +1,74 @@
+/* Return scope DIEs containing given 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "libdwP.h"
+#include <assert.h>
+#include <stdlib.h>
+
+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, &scope_visitor, NULL, &info);
+ if (result > 0)
+ *scopes = info;
+ return result;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getscopevar.c b/3rdparty/elfutils/libdw/dwarf_getscopevar.c
new file mode 100644
index 0000000..eb50c0a
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getscopevar.c
@@ -0,0 +1,154 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <string.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+/* 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);
+}
+
+/* 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;
+ inline bool file_matches (Dwarf_Files *files, size_t idx)
+ {
+ 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;
+ }
+
+ /* 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 (files, i))
+ 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/3rdparty/elfutils/libdw/dwarf_getsrc_die.c b/3rdparty/elfutils/libdw/dwarf_getsrc_die.c
new file mode 100644
index 0000000..1914cdf
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getsrc_die.c
@@ -0,0 +1,78 @@
+/* Find line information for address.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <assert.h>
+
+
+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. */
+ size_t l = 0, u = nlines;
+ while (l < u)
+ {
+ size_t idx = (l + u) / 2;
+ if (addr < lines->info[idx].addr)
+ u = idx;
+ else if (addr > lines->info[idx].addr || lines->info[idx].end_sequence)
+ l = idx + 1;
+ else
+ return &lines->info[idx];
+ }
+
+ if (nlines > 0)
+ assert (lines->info[nlines - 1].end_sequence);
+
+ /* If none were equal, the closest one below is what we want. We
+ never want the last one, because it's the end-sequence marker
+ with an address at the high bound of the CU's code. If the debug
+ information is faulty and no end-sequence marker is present, we
+ still ignore it. */
+ if (u > 0 && u < nlines && addr > lines->info[u - 1].addr)
+ {
+ while (lines->info[u - 1].end_sequence && u > 0)
+ --u;
+ if (u > 0)
+ return &lines->info[u - 1];
+ }
+
+ __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE);
+ return NULL;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_getsrc_file.c b/3rdparty/elfutils/libdw/dwarf_getsrc_file.c
new file mode 100644
index 0000000..5289c7d
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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/3rdparty/elfutils/libdw/dwarf_getsrcdirs.c b/3rdparty/elfutils/libdw/dwarf_getsrcdirs.c
new file mode 100644
index 0000000..47283ec
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getsrcdirs.c
@@ -0,0 +1,48 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_getsrcdirs (files, result, ndirs)
+ 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/3rdparty/elfutils/libdw/dwarf_getsrcfiles.c b/3rdparty/elfutils/libdw/dwarf_getsrcfiles.c
new file mode 100644
index 0000000..4bfc34b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getsrcfiles.c
@@ -0,0 +1,76 @@
+/* Return source file information of CU.
+ Copyright (C) 2004, 2005, 2013 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
+{
+ if (unlikely (cudie == NULL
+ || (INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit
+ && INTUSE(dwarf_tag) (cudie) != DW_TAG_partial_unit)))
+ return -1;
+
+ int res = -1;
+
+ /* Get the information if it is not already known. */
+ struct Dwarf_CU *const cu = cudie->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. */
+ 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/3rdparty/elfutils/libdw/dwarf_getsrclines.c b/3rdparty/elfutils/libdw/dwarf_getsrclines.c
new file mode 100644
index 0000000..053b30f
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getsrclines.c
@@ -0,0 +1,881 @@
+/* Return line number information of CU.
+ Copyright (C) 2004-2010, 2013, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <search.h>
+
+#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;
+}
+
+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 linelist *linelist = NULL;
+ size_t nlinelist = 0;
+
+ /* If there are a large number of lines don't blow up the stack.
+ Keep track of the last malloced linelist record and free them
+ through the next pointer at the end. */
+#define MAX_STACK_ALLOC 4096
+ struct linelist *malloc_linelist = NULL;
+
+ 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)
+ || unit_length < 2 + length + 5 * 1))
+ goto invalid_data;
+ lineendp = linep + unit_length;
+
+ /* The next element of the header is the version identifier. */
+ uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
+ if (unlikely (version < 2) || unlikely (version > 4))
+ {
+ __libdw_seterrno (DWARF_E_VERSION);
+ goto out;
+ }
+
+ /* Next comes the header length. */
+ Dwarf_Word header_length;
+ if (length == 4)
+ header_length = read_4ubyte_unaligned_inc (dbg, linep);
+ else
+ 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 (lineendp - linep < 5))
+ goto invalid_data;
+ max_ops_per_instr = *linep++;
+ if (unlikely (max_ops_per_instr == 0))
+ 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;
+
+ /* First comes the list of directories. Add the compilation
+ directory first since the index zero is used for it. */
+ struct dirlist
+ {
+ const char *dir;
+ size_t len;
+ struct dirlist *next;
+ } comp_dir_elem =
+ {
+ .dir = comp_dir,
+ .len = comp_dir ? strlen (comp_dir) : 0,
+ .next = NULL
+ };
+ struct dirlist *dirlist = &comp_dir_elem;
+ unsigned int ndirlist = 1;
+
+ // XXX Directly construct array to conserve memory?
+ while (*linep != 0)
+ {
+ struct dirlist *new_dir =
+ (struct dirlist *) alloca (sizeof (*new_dir));
+
+ new_dir->dir = (char *) linep;
+ uint8_t *endp = memchr (linep, '\0', lineendp - linep);
+ if (endp == NULL)
+ goto invalid_data;
+ new_dir->len = endp - linep;
+ new_dir->next = dirlist;
+ dirlist = new_dir;
+ ++ndirlist;
+ linep = endp + 1;
+ }
+ /* Skip the final NUL byte. */
+ ++linep;
+
+ /* Rearrange the list in array form. */
+ struct dirlist **dirarray
+ = (struct dirlist **) alloca (ndirlist * sizeof (*dirarray));
+ for (unsigned int n = ndirlist; n-- > 0; dirlist = dirlist->next)
+ dirarray[n] = dirlist;
+
+ /* Now read the files. */
+ struct filelist null_file =
+ {
+ .info =
+ {
+ .name = "???",
+ .mtime = 0,
+ .length = 0
+ },
+ .next = NULL
+ };
+ struct filelist *filelist = &null_file;
+ unsigned int nfilelist = 1;
+
+ if (unlikely (linep >= lineendp))
+ goto invalid_data;
+ while (*linep != 0)
+ {
+ struct filelist *new_file =
+ (struct filelist *) alloca (sizeof (*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.
+ The easiest thing is to convert the path in an
+ absolute path. */
+ 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);
+
+ new_file->next = filelist;
+ filelist = new_file;
+ ++nfilelist;
+ }
+ /* Skip the final NUL byte. */
+ ++linep;
+
+ /* 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. Initialize the
+ state machine registers (see 6.2.2 in the v2.1 specification). */
+ Dwarf_Word addr = 0;
+ unsigned int op_index = 0;
+ unsigned int file = 1;
+ int line = 1;
+ unsigned int column = 0;
+ uint_fast8_t is_stmt = default_is_stmt;
+ bool basic_block = false;
+ bool prologue_end = false;
+ bool epilogue_begin = false;
+ unsigned int isa = 0;
+ unsigned int discriminator = 0;
+
+ /* Apply the "operation advance" from a special opcode or
+ DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
+ inline void advance_pc (unsigned int op_advance)
+ {
+ addr += minimum_instr_len * ((op_index + op_advance)
+ / max_ops_per_instr);
+ op_index = (op_index + op_advance) % max_ops_per_instr;
+ }
+
+ /* Process the instructions. */
+
+ /* Adds a new line to the matrix.
+ We cannot simply define a function because we want to use alloca. */
+#define NEW_LINE(end_seq) \
+ do { \
+ struct linelist *ll = (nlinelist < MAX_STACK_ALLOC \
+ ? alloca (sizeof (struct linelist)) \
+ : malloc (sizeof (struct linelist))); \
+ if (nlinelist >= MAX_STACK_ALLOC) \
+ malloc_linelist = ll; \
+ if (unlikely (add_new_line (ll, end_seq))) \
+ goto invalid_data; \
+ } while (0)
+
+ inline bool add_new_line (struct linelist *new_line, bool end_sequence)
+ {
+ new_line->next = linelist;
+ new_line->sequence = nlinelist;
+ linelist = new_line;
+ ++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 = field; \
+ if (unlikely (new_line->line.field != 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;
+ }
+
+ 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. */
+ 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. */
+ basic_block = false;
+ prologue_end = false;
+ epilogue_begin = false;
+ 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. */
+ addr = 0;
+ op_index = 0;
+ file = 1;
+ line = 1;
+ column = 0;
+ is_stmt = default_is_stmt;
+ basic_block = false;
+ prologue_end = false;
+ epilogue_begin = false;
+ isa = 0;
+ discriminator = 0;
+ break;
+
+ case DW_LNE_set_address:
+ /* The value is an address. The size is defined as
+ apporiate for the target machine. We use the
+ address size field from the CU header. */
+ 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, &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 =
+ (struct filelist *) alloca (sizeof (*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. The easiest
+ thing is to convert the path in an
+ absolute path. */
+ cp = stpcpy (cp, dirarray[diridx]->dir);
+ *cp++ = '/';
+ strcpy (cp, fname);
+ }
+
+ new_file->info.mtime = mtime;
+ new_file->info.length = filelength;
+ new_file->next = filelist;
+ filelist = new_file;
+ ++nfilelist;
+ }
+ 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 (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. */
+ basic_block = false;
+ prologue_end = false;
+ epilogue_begin = false;
+ 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);
+ 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);
+ 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);
+ column = u128;
+ break;
+
+ case DW_LNS_negate_stmt:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ goto invalid_data;
+
+ is_stmt = 1 - is_stmt;
+ break;
+
+ case DW_LNS_set_basic_block:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ goto invalid_data;
+
+ 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;
+
+ addr += read_2ubyte_unaligned_inc (dbg, linep);
+ op_index = 0;
+ break;
+
+ case DW_LNS_set_prologue_end:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ goto invalid_data;
+
+ prologue_end = true;
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ goto invalid_data;
+
+ 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 (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];
+
+ files->nfiles = nfilelist;
+ while (nfilelist-- > 0)
+ {
+ files->info[nfilelist] = filelist->info;
+ filelist = filelist->next;
+ }
+ assert (filelist == 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) * 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 **) * 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. */
+ for (size_t i = nlinelist; i-- > 0; )
+ {
+ sortlines[i] = linelist;
+ linelist = linelist->next;
+ }
+ assert (linelist == NULL);
+
+ /* Sort by ascending address. */
+ qsort (sortlines, 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 = nlinelist;
+ for (size_t i = 0; i < 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 (nlinelist > 0)
+ lines->info[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_ALLOC; i < nlinelist; i++)
+ {
+ struct linelist *ll = malloc_linelist->next;
+ free (malloc_linelist);
+ malloc_linelist = ll;
+ }
+
+ 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 (unlikely (cudie == NULL
+ || (INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit
+ && INTUSE(dwarf_tag) (cudie) != DW_TAG_partial_unit)))
+ return -1;
+
+ /* Get the information if it is not already known. */
+ struct Dwarf_CU *const cu = cudie->cu;
+ if (cu->lines == NULL)
+ {
+ /* 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/3rdparty/elfutils/libdw/dwarf_getstring.c b/3rdparty/elfutils/libdw/dwarf_getstring.c
new file mode 100644
index 0000000..672bb27
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_getstring.c
@@ -0,0 +1,66 @@
+/* Get string.
+ Copyright (C) 2004 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_getstring (dbg, offset, lenp)
+ 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/3rdparty/elfutils/libdw/dwarf_hasattr.c b/3rdparty/elfutils/libdw/dwarf_hasattr.c
new file mode 100644
index 0000000..812c09b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_hasattr.c
@@ -0,0 +1,85 @@
+/* Check whether given DIE has specific attribute.
+ Copyright (C) 2003, 2005, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_hasattr (die, search_name)
+ 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))
+ {
+ invalid_dwarf:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return 0;
+ }
+
+ Dwarf *dbg = die->cu->dbg;
+
+ /* Search the name attribute. */
+ unsigned char *const endp
+ = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
+ + dbg->sectiondata[IDX_debug_abbrev]->d_size);
+
+ const unsigned char *attrp = abbrevp->attrp;
+ while (1)
+ {
+ /* Are we still in bounds? This test needs to be refined. */
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+
+ /* Get attribute name and form. */
+ unsigned int attr_name;
+ get_uleb128 (attr_name, attrp, endp);
+ unsigned int attr_form;
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+ get_uleb128 (attr_form, attrp, endp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 || attr_form == 0)
+ return 0;
+
+ if (attr_name == search_name)
+ return 1;
+ }
+}
+INTDEF (dwarf_hasattr)
diff --git a/3rdparty/elfutils/libdw/dwarf_hasattr_integrate.c b/3rdparty/elfutils/libdw/dwarf_hasattr_integrate.c
new file mode 100644
index 0000000..2d5348c
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_hasattr_integrate.c
@@ -0,0 +1,59 @@
+/* Check whether DIE has specific attribute, integrating DW_AT_abstract_origin.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+int
+dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name)
+{
+ Dwarf_Die die_mem;
+
+ 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);
+
+ return 0;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_haschildren.c b/3rdparty/elfutils/libdw/dwarf_haschildren.c
new file mode 100644
index 0000000..d0ce51e
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_haschildren.c
@@ -0,0 +1,52 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <string.h>
+
+
+int
+dwarf_haschildren (die)
+ 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/3rdparty/elfutils/libdw/dwarf_hasform.c b/3rdparty/elfutils/libdw/dwarf_hasform.c
new file mode 100644
index 0000000..a95ca9e
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_hasform.c
@@ -0,0 +1,47 @@
+/* Check whether given attribute has specific form.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_hasform (attr, search_form)
+ Dwarf_Attribute *attr;
+ unsigned int search_form;
+{
+ if (attr == NULL)
+ return 0;
+
+ return attr->form == search_form;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_haspc.c b/3rdparty/elfutils/libdw/dwarf_haspc.c
new file mode 100644
index 0000000..47e2b05
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+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/3rdparty/elfutils/libdw/dwarf_highpc.c b/3rdparty/elfutils/libdw/dwarf_highpc.c
new file mode 100644
index 0000000..8bf93f0
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_highpc.c
@@ -0,0 +1,68 @@
+/* Return high PC attribute of DIE.
+ Copyright (C) 2003, 2005, 2012 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_highpc (die, return_addr)
+ Dwarf_Die *die;
+ Dwarf_Addr *return_addr;
+{
+ Dwarf_Attribute attr_high_mem;
+ Dwarf_Attribute *attr_high = INTUSE(dwarf_attr) (die, DW_AT_high_pc,
+ &attr_high_mem);
+ if (attr_high == NULL)
+ return -1;
+
+ if (attr_high->form == DW_FORM_addr)
+ return INTUSE(dwarf_formaddr) (attr_high, return_addr);
+
+ /* DWARF 4 allows high_pc to be a constant offset from low_pc. */
+ Dwarf_Attribute attr_low_mem;
+ if (INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_low_pc,
+ &attr_low_mem),
+ return_addr) == 0)
+ {
+ Dwarf_Word uval;
+ if (INTUSE(dwarf_formudata) (attr_high, &uval) == 0)
+ {
+ *return_addr += uval;
+ return 0;
+ }
+ __libdw_seterrno (DWARF_E_NO_ADDR);
+ }
+ return -1;
+}
+INTDEF(dwarf_highpc)
diff --git a/3rdparty/elfutils/libdw/dwarf_lineaddr.c b/3rdparty/elfutils/libdw/dwarf_lineaddr.c
new file mode 100644
index 0000000..4e1952d
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_linebeginstatement.c b/3rdparty/elfutils/libdw/dwarf_linebeginstatement.c
new file mode 100644
index 0000000..4854c56
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineblock.c b/3rdparty/elfutils/libdw/dwarf_lineblock.c
new file mode 100644
index 0000000..e3c7f41
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_linecol.c b/3rdparty/elfutils/libdw/dwarf_linecol.c
new file mode 100644
index 0000000..c667b1b
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_linediscriminator.c b/3rdparty/elfutils/libdw/dwarf_linediscriminator.c
new file mode 100644
index 0000000..552205a
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineendsequence.c b/3rdparty/elfutils/libdw/dwarf_lineendsequence.c
new file mode 100644
index 0000000..61bde93
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineepiloguebegin.c b/3rdparty/elfutils/libdw/dwarf_lineepiloguebegin.c
new file mode 100644
index 0000000..b914787
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineisa.c b/3rdparty/elfutils/libdw/dwarf_lineisa.c
new file mode 100644
index 0000000..30181fc
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineno.c b/3rdparty/elfutils/libdw/dwarf_lineno.c
new file mode 100644
index 0000000..009999c
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineop_index.c b/3rdparty/elfutils/libdw/dwarf_lineop_index.c
new file mode 100644
index 0000000..9ea4ef4
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lineprologueend.c b/3rdparty/elfutils/libdw/dwarf_lineprologueend.c
new file mode 100644
index 0000000..6ba8be2
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_linesrc.c b/3rdparty/elfutils/libdw/dwarf_linesrc.c
new file mode 100644
index 0000000..27b5990
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_lowpc.c b/3rdparty/elfutils/libdw/dwarf_lowpc.c
new file mode 100644
index 0000000..4677aed
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_lowpc.c
@@ -0,0 +1,49 @@
+/* Return low PC attribute of DIE.
+ Copyright (C) 2003, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_lowpc (die, return_addr)
+ Dwarf_Die *die;
+ Dwarf_Addr *return_addr;
+{
+ Dwarf_Attribute attr_mem;
+
+ return INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_low_pc,
+ &attr_mem),
+ return_addr);
+}
+INTDEF(dwarf_lowpc)
diff --git a/3rdparty/elfutils/libdw/dwarf_macro_getparamcnt.c b/3rdparty/elfutils/libdw/dwarf_macro_getparamcnt.c
new file mode 100644
index 0000000..e218eb1
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_macro_getsrcfiles.c b/3rdparty/elfutils/libdw/dwarf_macro_getsrcfiles.c
new file mode 100644
index 0000000..cc19043
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_macro_getsrcfiles.c
@@ -0,0 +1,88 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+int
+dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
+ Dwarf_Files **files, size_t *nfiles)
+{
+ if (macro == NULL)
+ return -1;
+
+ 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/3rdparty/elfutils/libdw/dwarf_macro_opcode.c b/3rdparty/elfutils/libdw/dwarf_macro_opcode.c
new file mode 100644
index 0000000..8607777
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_macro_param.c b/3rdparty/elfutils/libdw/dwarf_macro_param.c
new file mode 100644
index 0000000..bd846a7
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_macro_param1.c b/3rdparty/elfutils/libdw/dwarf_macro_param1.c
new file mode 100644
index 0000000..87ce003
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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, &param) != 0)
+ return -1;
+
+ return dwarf_formudata (&param, paramp);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_macro_param2.c b/3rdparty/elfutils/libdw/dwarf_macro_param2.c
new file mode 100644
index 0000000..cc902c9
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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, &param) != 0)
+ return -1;
+
+ if (param.form == DW_FORM_string
+ || param.form == DW_FORM_strp)
+ {
+ *strp = dwarf_formstring (&param);
+ return 0;
+ }
+ else
+ return dwarf_formudata (&param, paramp);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_next_cfi.c b/3rdparty/elfutils/libdw/dwarf_next_cfi.c
new file mode 100644
index 0000000..b5af49e
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_next_cfi.c
@@ -0,0 +1,246 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include "encoded-value.h"
+
+#include <string.h>
+
+
+int
+dwarf_next_cfi (e_ident, data, eh_frame_p, off, next_off, entry)
+ 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))
+ {
+ *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);
+ }
+ 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/3rdparty/elfutils/libdw/dwarf_nextcu.c b/3rdparty/elfutils/libdw/dwarf_nextcu.c
new file mode 100644
index 0000000..875d869
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_nextcu.c
@@ -0,0 +1,199 @@
+/* Advance to next CU header.
+ Copyright (C) 2002-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwP.h>
+#include <dwarf.h>
+
+
+int
+dwarf_next_unit (dwarf, off, next_off, header_sizep, versionp, abbrev_offsetp,
+ address_sizep, offset_sizep, type_signaturep, type_offsetp)
+ 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;
+{
+ const bool debug_types = type_signaturep != NULL;
+ const size_t sec_idx = 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 section to the beginning of the
+ CU entry. */
+ const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
+ const unsigned char *bytes = data + off;
+
+ /* The format of the CU header is described in dwarf2p1 7.5.1:
+
+ 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).
+
+ 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. 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).
+
+ 4. 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. */
+ 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;
+ }
+
+ /* Now we know how large the header is. */
+ if (unlikely (DIE_OFFSET_FROM_CU_OFFSET (off, offset_size, debug_types)
+ >= dwarf->sectiondata[sec_idx]->d_size))
+ {
+ *next_off = -1;
+ return 1;
+ }
+
+ if (length == DWARF3_LENGTH_64_BIT)
+ /* This is a 64-bit DWARF format. */
+ length = read_8ubyte_unaligned_inc (dwarf, bytes);
+
+ /* Read the version stamp. Always a 16-bit value. */
+ uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, 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. */
+ uint64_t abbrev_offset;
+ if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
+ &abbrev_offset, IDX_debug_abbrev, 0))
+ return -1;
+
+ /* The address size. Always an 8-bit value. */
+ uint8_t address_size = *bytes++;
+
+ if (debug_types)
+ {
+ uint64_t type_sig8 = read_8ubyte_unaligned_inc (dwarf, bytes);
+
+ Dwarf_Off type_offset;
+ if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
+ &type_offset, sec_idx, 0))
+ return -1;
+
+ /* Validate that the TYPE_OFFSET points past the header. */
+ if (unlikely (type_offset < (size_t) (bytes - (data + off))))
+ goto invalid;
+
+ *type_signaturep = type_sig8;
+ if (type_offsetp != NULL)
+ *type_offsetp = type_offset;
+ }
+
+ /* Store the header length. */
+ if (header_sizep != NULL)
+ *header_sizep = bytes - (data + off);
+
+ if (versionp != NULL)
+ *versionp = version;
+
+ 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;
+
+ /* See definition of DIE_OFFSET_FROM_CU_OFFSET macro
+ for an explanation of the trick in this expression. */
+ *next_off = off + 2 * offset_size - 4 + length;
+
+ return 0;
+}
+INTDEF(dwarf_next_unit)
+
+int
+dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
+ address_sizep, offset_sizep)
+ 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/3rdparty/elfutils/libdw/dwarf_offabbrev.c b/3rdparty/elfutils/libdw/dwarf_offabbrev.c
new file mode 100644
index 0000000..27cdad6
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_offdie.c b/3rdparty/elfutils/libdw/dwarf_offdie.c
new file mode 100644
index 0000000..b5dd405
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_offdie.c
@@ -0,0 +1,90 @@
+/* Return DIE at given offset.
+ Copyright (C) 2002-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#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 (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 (dbg, offset, result)
+ Dwarf *dbg;
+ Dwarf_Off offset;
+ Dwarf_Die *result;
+{
+ return __libdw_offdie (dbg, offset, result, false);
+}
+INTDEF(dwarf_offdie)
+
+Dwarf_Die *
+dwarf_offdie_types (dbg, offset, result)
+ Dwarf *dbg;
+ Dwarf_Off offset;
+ Dwarf_Die *result;
+{
+ return __libdw_offdie (dbg, offset, result, true);
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_onearange.c b/3rdparty/elfutils/libdw/dwarf_onearange.c
new file mode 100644
index 0000000..de49f6c
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_onesrcline.c b/3rdparty/elfutils/libdw/dwarf_onesrcline.c
new file mode 100644
index 0000000..5d3c3de
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdw/dwarf_peel_type.c b/3rdparty/elfutils/libdw/dwarf_peel_type.c
new file mode 100644
index 0000000..a110bc5
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_peel_type.c
@@ -0,0 +1,74 @@
+/* Peel type aliases and qualifier tags from a type DIE.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <string.h>
+
+
+int
+dwarf_peel_type (die, result)
+ Dwarf_Die *die;
+ Dwarf_Die *result;
+{
+ int tag;
+
+ /* Ignore previous errors. */
+ if (die == NULL)
+ return -1;
+
+ *result = *die;
+ tag = INTUSE (dwarf_tag) (result);
+ while (tag == DW_TAG_typedef
+ || tag == DW_TAG_const_type
+ || tag == DW_TAG_volatile_type
+ || tag == DW_TAG_restrict_type)
+ {
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (die, DW_AT_type,
+ &attr_mem);
+ if (attr == NULL)
+ return 1;
+
+ result = INTUSE (dwarf_formref_die) (attr, result);
+ if (result == NULL)
+ return -1;
+
+ tag = INTUSE (dwarf_tag) (result);
+ }
+
+ if (tag == DW_TAG_invalid)
+ return -1;
+
+ return 0;
+}
+INTDEF(dwarf_peel_type)
diff --git a/3rdparty/elfutils/libdw/dwarf_ranges.c b/3rdparty/elfutils/libdw/dwarf_ranges.c
new file mode 100644
index 0000000..d9b7293
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_ranges.c
@@ -0,0 +1,190 @@
+/* Enumerate the PC ranges covered by a DIE.
+ Copyright (C) 2005, 2007, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <assert.h>
+
+/* 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 -1. */
+internal_function int
+__libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
+ unsigned char **addrp, int width,
+ Dwarf_Addr *beginp, Dwarf_Addr *endp,
+ Dwarf_Addr *basep)
+{
+ Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1
+ : (Elf64_Addr) (Elf32_Addr) -1);
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+
+ unsigned char *addr = *addrp;
+ 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))
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ if (basep != NULL)
+ *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;
+ *endp = end;
+
+ 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. */
+
+ const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges];
+ if (d == NULL && offset != 0)
+ {
+ __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
+ return -1;
+ }
+
+ unsigned char *readp;
+ unsigned char *readendp;
+ if (offset == 0)
+ {
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges,
+ &attr_mem);
+ if (attr == NULL)
+ /* No PC attributes in this DIE at all, so an empty range list. */
+ return 0;
+
+ Dwarf_Word start_offset;
+ if ((readp = __libdw_formptr (attr, IDX_debug_ranges,
+ DWARF_E_NO_DEBUG_RANGES,
+ &readendp, &start_offset)) == NULL)
+ return -1;
+
+ offset = start_offset;
+ assert ((Dwarf_Word) offset == start_offset);
+
+ /* Fetch the CU's base address. */
+ Dwarf_Die cudie = CUDIE (attr->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. */
+ if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0)
+ && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
+ DW_AT_entry_pc,
+ &attr_mem),
+ basep) != 0)
+ {
+ if (INTUSE(dwarf_errno) () == 0)
+ {
+ invalid:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ }
+ return -1;
+ }
+ }
+ else
+ {
+ if (__libdw_offset_in_section (die->cu->dbg,
+ IDX_debug_ranges, offset, 1))
+ return -1l;
+
+ readp = d->d_buf + offset;
+ readendp = d->d_buf + d->d_size;
+ }
+
+ next:
+ if (readendp - readp < die->cu->address_size * 2)
+ goto invalid;
+
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+
+ switch (__libdw_read_begin_end_pair_inc (die->cu->dbg, IDX_debug_ranges,
+ &readp, die->cu->address_size,
+ &begin, &end, basep))
+ {
+ case 0:
+ break;
+ case 1:
+ goto next;
+ case 2:
+ return 0;
+ default:
+ return -1l;
+ }
+
+ /* We have an address range entry. */
+ *startp = *basep + begin;
+ *endp = *basep + end;
+ return readp - (unsigned char *) d->d_buf;
+}
+INTDEF (dwarf_ranges)
diff --git a/3rdparty/elfutils/libdw/dwarf_setalt.c b/3rdparty/elfutils/libdw/dwarf_setalt.c
new file mode 100644
index 0000000..9bd566f
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_setalt.c
@@ -0,0 +1,40 @@
+/* Provides the data referenced by the .gnu_debugaltlink section.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+void
+dwarf_setalt (Dwarf *main, Dwarf *alt)
+{
+ main->alt_dwarf = alt;
+}
+INTDEF (dwarf_setalt)
diff --git a/3rdparty/elfutils/libdw/dwarf_siblingof.c b/3rdparty/elfutils/libdw/dwarf_siblingof.c
new file mode 100644
index 0000000..27830ea
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_siblingof.c
@@ -0,0 +1,136 @@
+/* Return sibling of given DIE.
+ Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <string.h>
+
+
+int
+dwarf_siblingof (die, result)
+ Dwarf_Die *die;
+ Dwarf_Die *result;
+{
+ /* Ignore previous errors. */
+ if (die == NULL)
+ return -1;
+
+ if (result == NULL)
+ return -1;
+
+ 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 = this_die.addr;
+ /* End of the buffer. */
+ unsigned char *endp = sibattr.cu->endp;
+
+ /* 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;
+
+ /* 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;
+
+
+ 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. */
+ 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/3rdparty/elfutils/libdw/dwarf_sig8_hash.c b/3rdparty/elfutils/libdw/dwarf_sig8_hash.c
new file mode 100644
index 0000000..043cac7
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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 <dynamicsizehash.c>
diff --git a/3rdparty/elfutils/libdw/dwarf_sig8_hash.h b/3rdparty/elfutils/libdw/dwarf_sig8_hash.h
new file mode 100644
index 0000000..705ffbc
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_sig8_hash.h
@@ -0,0 +1,38 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _DWARF_SIG8_HASH_H
+#define _DWARF_SIG8_HASH_H 1
+
+#define NAME Dwarf_Sig8_Hash
+#define TYPE struct Dwarf_CU *
+#define COMPARE(a, b) (0)
+
+#include <dynamicsizehash.h>
+
+#endif /* dwarf_sig8_hash.h */
diff --git a/3rdparty/elfutils/libdw/dwarf_srclang.c b/3rdparty/elfutils/libdw/dwarf_srclang.c
new file mode 100644
index 0000000..6cc06ff
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_srclang.c
@@ -0,0 +1,51 @@
+/* Return source language attribute of DIE.
+ Copyright (C) 2003-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_srclang (die)
+ 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/3rdparty/elfutils/libdw/dwarf_tag.c b/3rdparty/elfutils/libdw/dwarf_tag.c
new file mode 100644
index 0000000..0b1a4b0
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_tag.c
@@ -0,0 +1,95 @@
+/* Return tag of given DIE.
+ Copyright (C) 2003-2011, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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, NULL);
+ 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 (die)
+ 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/3rdparty/elfutils/libdw/dwarf_whatattr.c b/3rdparty/elfutils/libdw/dwarf_whatattr.c
new file mode 100644
index 0000000..8fe5535
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_whatattr.c
@@ -0,0 +1,43 @@
+/* Return attribute code of given attribute.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_whatattr (attr)
+ Dwarf_Attribute *attr;
+{
+ return attr == NULL ? 0 : attr->code;
+}
diff --git a/3rdparty/elfutils/libdw/dwarf_whatform.c b/3rdparty/elfutils/libdw/dwarf_whatform.c
new file mode 100644
index 0000000..1d0d14b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwarf_whatform.c
@@ -0,0 +1,43 @@
+/* Return form code of given attribute.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_whatform (attr)
+ Dwarf_Attribute *attr;
+{
+ return attr == NULL ? 0 : attr->form;
+}
diff --git a/3rdparty/elfutils/libdw/dwheaders.pri b/3rdparty/elfutils/libdw/dwheaders.pri
new file mode 100644
index 0000000..254b586
--- /dev/null
+++ b/3rdparty/elfutils/libdw/dwheaders.pri
@@ -0,0 +1,12 @@
+HEADERS += \
+ $$PWD/cfi.h \
+ $$PWD/dwarf_abbrev_hash.h \
+ $$PWD/dwarf_sig8_hash.h \
+ $$PWD/dwarf.h \
+ $$PWD/encoded-value.h \
+ $$PWD/known-dwarf.h \
+ $$PWD/libdw.h \
+ $$PWD/libdwP.h \
+ $$PWD/memory-access.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/libdw/encoded-value.h b/3rdparty/elfutils/libdw/encoded-value.h
new file mode 100644
index 0000000..ae9a38f
--- /dev/null
+++ b/3rdparty/elfutils/libdw/encoded-value.h
@@ -0,0 +1,197 @@
+/* DW_EH_PE_* support for libdw unwinder.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _ENCODED_VALUE_H
+#define _ENCODED_VALUE_H 1
+
+#include <dwarf.h>
+#include <stdlib.h>
+#include "libdwP.h"
+
+
+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;
+ }
+
+ default:
+ abort ();
+ return 0;
+ }
+}
+
+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. */
+
+ if (width == 4)
+ *ret = read_4ubyte_unaligned_inc (cache, *addrp);
+ else
+ *ret = read_8ubyte_unaligned_inc (cache, *addrp);
+ return 0;
+}
+
+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);
+ 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:
+ abort ();
+ }
+
+ Dwarf_Addr value;
+ switch (encoding & 0x0f)
+ {
+ case DW_EH_PE_udata2:
+ value = read_2ubyte_unaligned_inc (cache, *p);
+ break;
+
+ case DW_EH_PE_sdata2:
+ value = read_2sbyte_unaligned_inc (cache, *p);
+ break;
+
+ case DW_EH_PE_udata4:
+ if (__libdw_cfi_read_address_inc (cache, p, 4, &value))
+ return true;
+ break;
+
+ case DW_EH_PE_sdata4:
+ if (__libdw_cfi_read_address_inc (cache, p, 4, &value))
+ return true;
+ value = (Dwarf_Sword) (Elf32_Sword) value; /* Sign-extend. */
+ break;
+
+ case DW_EH_PE_udata8:
+ case DW_EH_PE_sdata8:
+ if (__libdw_cfi_read_address_inc (cache, p, 8, &value))
+ return true;
+ break;
+
+ case DW_EH_PE_absptr:
+ if (__libdw_cfi_read_address_inc (cache, p, 0, &value))
+ return true;
+ break;
+
+ case DW_EH_PE_uleb128:
+ // XXX we trust there is enough data.
+ get_uleb128 (value, *p, *p + len_leb128 (Dwarf_Addr));
+ break;
+
+ case DW_EH_PE_sleb128:
+ // XXX we trust there is enough data.
+ get_sleb128 (value, *p, *p + len_leb128 (Dwarf_Addr));
+ break;
+
+ default:
+ abort ();
+ }
+
+ *result += value;
+
+ if (encoding & DW_EH_PE_indirect)
+ {
+ if (unlikely (*result < cache->frame_vaddr))
+ return true;
+ *result -= cache->frame_vaddr;
+ if (unlikely (*result > (cache->data->d.d_size
+ - encoded_value_size (NULL, cache->e_ident,
+ DW_EH_PE_absptr, NULL))))
+ return true;
+ const uint8_t *ptr = cache->data->d.d_buf + *result;
+ return __libdw_cfi_read_address_inc (cache, &ptr, 0, result);
+ }
+
+ return false;
+}
+
+#endif /* encoded-value.h */
diff --git a/3rdparty/elfutils/libdw/fde.c b/3rdparty/elfutils/libdw/fde.c
new file mode 100644
index 0000000..18a522b
--- /dev/null
+++ b/3rdparty/elfutils/libdw/fde.c
@@ -0,0 +1,297 @@
+/* FDE reading.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <search.h>
+#include <stdlib.h>
+
+#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;
+
+ 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. */
+ if (tsearch (fde, &cache->fde_tree, &compare_fde) == NULL)
+ {
+ free (fde);
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return NULL;
+ }
+
+ 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);
+
+ /* Dummy used by read_encoded_value. */
+ Dwarf_CFI dummy_cfi =
+ {
+ .e_ident = cache->e_ident,
+ .datarel = cache->search_table_vaddr,
+ .frame_vaddr = cache->search_table_vaddr,
+ };
+
+ size_t l = 0, u = cache->search_table_entries;
+ while (l < u)
+ {
+ size_t idx = (l + u) / 2;
+
+ 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/3rdparty/elfutils/libdw/frame-cache.c b/3rdparty/elfutils/libdw/frame-cache.c
new file mode 100644
index 0000000..54a1cc9
--- /dev/null
+++ b/3rdparty/elfutils/libdw/frame-cache.c
@@ -0,0 +1,66 @@
+/* Frame cache 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <search.h>
+#include <stdlib.h>
+
+
+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);
+}
diff --git a/3rdparty/elfutils/libdw/known-dwarf.h b/3rdparty/elfutils/libdw/known-dwarf.h
new file mode 100644
index 0000000..2aeada9
--- /dev/null
+++ b/3rdparty/elfutils/libdw/known-dwarf.h
@@ -0,0 +1,629 @@
+/* Generated by config/known-dwarf.awk from libdw/dwarf.h contents. */
+
+#define ALL_KNOWN_DW_ACCESS \
+ ONE_KNOWN_DW_ACCESS (private, DW_ACCESS_private) \
+ ONE_KNOWN_DW_ACCESS (protected, DW_ACCESS_protected) \
+ ONE_KNOWN_DW_ACCESS (public, DW_ACCESS_public) \
+ /* End of DW_ACCESS_*. */
+
+#define ALL_KNOWN_DW_AT \
+ ONE_KNOWN_DW_AT (GNU_all_call_sites, DW_AT_GNU_all_call_sites) \
+ ONE_KNOWN_DW_AT (GNU_all_source_call_sites, DW_AT_GNU_all_source_call_sites) \
+ ONE_KNOWN_DW_AT (GNU_all_tail_call_sites, DW_AT_GNU_all_tail_call_sites) \
+ ONE_KNOWN_DW_AT (GNU_call_site_data_value, DW_AT_GNU_call_site_data_value) \
+ ONE_KNOWN_DW_AT (GNU_call_site_target, DW_AT_GNU_call_site_target) \
+ ONE_KNOWN_DW_AT (GNU_call_site_target_clobbered, DW_AT_GNU_call_site_target_clobbered) \
+ ONE_KNOWN_DW_AT (GNU_call_site_value, DW_AT_GNU_call_site_value) \
+ ONE_KNOWN_DW_AT (GNU_deleted, DW_AT_GNU_deleted) \
+ ONE_KNOWN_DW_AT (GNU_exclusive_locks_required, DW_AT_GNU_exclusive_locks_required) \
+ ONE_KNOWN_DW_AT (GNU_guarded, DW_AT_GNU_guarded) \
+ ONE_KNOWN_DW_AT (GNU_guarded_by, DW_AT_GNU_guarded_by) \
+ ONE_KNOWN_DW_AT (GNU_locks_excluded, DW_AT_GNU_locks_excluded) \
+ ONE_KNOWN_DW_AT (GNU_macros, DW_AT_GNU_macros) \
+ ONE_KNOWN_DW_AT (GNU_odr_signature, DW_AT_GNU_odr_signature) \
+ ONE_KNOWN_DW_AT (GNU_pt_guarded, DW_AT_GNU_pt_guarded) \
+ ONE_KNOWN_DW_AT (GNU_pt_guarded_by, DW_AT_GNU_pt_guarded_by) \
+ ONE_KNOWN_DW_AT (GNU_shared_locks_required, DW_AT_GNU_shared_locks_required) \
+ ONE_KNOWN_DW_AT (GNU_tail_call, DW_AT_GNU_tail_call) \
+ ONE_KNOWN_DW_AT (GNU_template_name, DW_AT_GNU_template_name) \
+ ONE_KNOWN_DW_AT (GNU_vector, DW_AT_GNU_vector) \
+ ONE_KNOWN_DW_AT (MIPS_abstract_name, DW_AT_MIPS_abstract_name) \
+ ONE_KNOWN_DW_AT (MIPS_allocatable_dopetype, DW_AT_MIPS_allocatable_dopetype) \
+ ONE_KNOWN_DW_AT (MIPS_assumed_shape_dopetype, DW_AT_MIPS_assumed_shape_dopetype) \
+ ONE_KNOWN_DW_AT (MIPS_assumed_size, DW_AT_MIPS_assumed_size) \
+ ONE_KNOWN_DW_AT (MIPS_clone_origin, DW_AT_MIPS_clone_origin) \
+ ONE_KNOWN_DW_AT (MIPS_epilog_begin, DW_AT_MIPS_epilog_begin) \
+ ONE_KNOWN_DW_AT (MIPS_fde, DW_AT_MIPS_fde) \
+ ONE_KNOWN_DW_AT (MIPS_has_inlines, DW_AT_MIPS_has_inlines) \
+ ONE_KNOWN_DW_AT (MIPS_linkage_name, DW_AT_MIPS_linkage_name) \
+ ONE_KNOWN_DW_AT (MIPS_loop_begin, DW_AT_MIPS_loop_begin) \
+ ONE_KNOWN_DW_AT (MIPS_loop_unroll_factor, DW_AT_MIPS_loop_unroll_factor) \
+ ONE_KNOWN_DW_AT (MIPS_ptr_dopetype, DW_AT_MIPS_ptr_dopetype) \
+ ONE_KNOWN_DW_AT (MIPS_software_pipeline_depth, DW_AT_MIPS_software_pipeline_depth) \
+ ONE_KNOWN_DW_AT (MIPS_stride, DW_AT_MIPS_stride) \
+ ONE_KNOWN_DW_AT (MIPS_stride_byte, DW_AT_MIPS_stride_byte) \
+ ONE_KNOWN_DW_AT (MIPS_stride_elem, DW_AT_MIPS_stride_elem) \
+ ONE_KNOWN_DW_AT (MIPS_tail_loop_begin, DW_AT_MIPS_tail_loop_begin) \
+ ONE_KNOWN_DW_AT (abstract_origin, DW_AT_abstract_origin) \
+ ONE_KNOWN_DW_AT (accessibility, DW_AT_accessibility) \
+ ONE_KNOWN_DW_AT (address_class, DW_AT_address_class) \
+ ONE_KNOWN_DW_AT (allocated, DW_AT_allocated) \
+ ONE_KNOWN_DW_AT (artificial, DW_AT_artificial) \
+ ONE_KNOWN_DW_AT (associated, DW_AT_associated) \
+ ONE_KNOWN_DW_AT (base_types, DW_AT_base_types) \
+ ONE_KNOWN_DW_AT (binary_scale, DW_AT_binary_scale) \
+ ONE_KNOWN_DW_AT (bit_offset, DW_AT_bit_offset) \
+ ONE_KNOWN_DW_AT (bit_size, DW_AT_bit_size) \
+ ONE_KNOWN_DW_AT (bit_stride, DW_AT_bit_stride) \
+ ONE_KNOWN_DW_AT (body_begin, DW_AT_body_begin) \
+ ONE_KNOWN_DW_AT (body_end, DW_AT_body_end) \
+ ONE_KNOWN_DW_AT (byte_size, DW_AT_byte_size) \
+ ONE_KNOWN_DW_AT (byte_stride, DW_AT_byte_stride) \
+ ONE_KNOWN_DW_AT (call_column, DW_AT_call_column) \
+ ONE_KNOWN_DW_AT (call_file, DW_AT_call_file) \
+ ONE_KNOWN_DW_AT (call_line, DW_AT_call_line) \
+ ONE_KNOWN_DW_AT (calling_convention, DW_AT_calling_convention) \
+ ONE_KNOWN_DW_AT (common_reference, DW_AT_common_reference) \
+ ONE_KNOWN_DW_AT (comp_dir, DW_AT_comp_dir) \
+ ONE_KNOWN_DW_AT (const_expr, DW_AT_const_expr) \
+ ONE_KNOWN_DW_AT (const_value, DW_AT_const_value) \
+ ONE_KNOWN_DW_AT (containing_type, DW_AT_containing_type) \
+ ONE_KNOWN_DW_AT (count, DW_AT_count) \
+ ONE_KNOWN_DW_AT (data_bit_offset, DW_AT_data_bit_offset) \
+ ONE_KNOWN_DW_AT (data_location, DW_AT_data_location) \
+ ONE_KNOWN_DW_AT (data_member_location, DW_AT_data_member_location) \
+ ONE_KNOWN_DW_AT (decimal_scale, DW_AT_decimal_scale) \
+ ONE_KNOWN_DW_AT (decimal_sign, DW_AT_decimal_sign) \
+ ONE_KNOWN_DW_AT (decl_column, DW_AT_decl_column) \
+ ONE_KNOWN_DW_AT (decl_file, DW_AT_decl_file) \
+ ONE_KNOWN_DW_AT (decl_line, DW_AT_decl_line) \
+ ONE_KNOWN_DW_AT (declaration, DW_AT_declaration) \
+ ONE_KNOWN_DW_AT (default_value, DW_AT_default_value) \
+ ONE_KNOWN_DW_AT (description, DW_AT_description) \
+ ONE_KNOWN_DW_AT (digit_count, DW_AT_digit_count) \
+ ONE_KNOWN_DW_AT (discr, DW_AT_discr) \
+ ONE_KNOWN_DW_AT (discr_list, DW_AT_discr_list) \
+ ONE_KNOWN_DW_AT (discr_value, DW_AT_discr_value) \
+ ONE_KNOWN_DW_AT (element_list, DW_AT_element_list) \
+ ONE_KNOWN_DW_AT (elemental, DW_AT_elemental) \
+ ONE_KNOWN_DW_AT (encoding, DW_AT_encoding) \
+ ONE_KNOWN_DW_AT (endianity, DW_AT_endianity) \
+ ONE_KNOWN_DW_AT (entry_pc, DW_AT_entry_pc) \
+ ONE_KNOWN_DW_AT (enum_class, DW_AT_enum_class) \
+ ONE_KNOWN_DW_AT (explicit, DW_AT_explicit) \
+ ONE_KNOWN_DW_AT (extension, DW_AT_extension) \
+ ONE_KNOWN_DW_AT (external, DW_AT_external) \
+ ONE_KNOWN_DW_AT (frame_base, DW_AT_frame_base) \
+ ONE_KNOWN_DW_AT (friend, DW_AT_friend) \
+ ONE_KNOWN_DW_AT (high_pc, DW_AT_high_pc) \
+ ONE_KNOWN_DW_AT (identifier_case, DW_AT_identifier_case) \
+ ONE_KNOWN_DW_AT (import, DW_AT_import) \
+ ONE_KNOWN_DW_AT (inline, DW_AT_inline) \
+ ONE_KNOWN_DW_AT (is_optional, DW_AT_is_optional) \
+ ONE_KNOWN_DW_AT (language, DW_AT_language) \
+ ONE_KNOWN_DW_AT (linkage_name, DW_AT_linkage_name) \
+ ONE_KNOWN_DW_AT (location, DW_AT_location) \
+ ONE_KNOWN_DW_AT (low_pc, DW_AT_low_pc) \
+ ONE_KNOWN_DW_AT (lower_bound, DW_AT_lower_bound) \
+ ONE_KNOWN_DW_AT (mac_info, DW_AT_mac_info) \
+ ONE_KNOWN_DW_AT (macro_info, DW_AT_macro_info) \
+ ONE_KNOWN_DW_AT (main_subprogram, DW_AT_main_subprogram) \
+ ONE_KNOWN_DW_AT (member, DW_AT_member) \
+ ONE_KNOWN_DW_AT (mutable, DW_AT_mutable) \
+ ONE_KNOWN_DW_AT (name, DW_AT_name) \
+ ONE_KNOWN_DW_AT (namelist_item, DW_AT_namelist_item) \
+ ONE_KNOWN_DW_AT (noreturn, DW_AT_noreturn) \
+ ONE_KNOWN_DW_AT (object_pointer, DW_AT_object_pointer) \
+ ONE_KNOWN_DW_AT (ordering, DW_AT_ordering) \
+ ONE_KNOWN_DW_AT (picture_string, DW_AT_picture_string) \
+ ONE_KNOWN_DW_AT (priority, DW_AT_priority) \
+ ONE_KNOWN_DW_AT (producer, DW_AT_producer) \
+ ONE_KNOWN_DW_AT (prototyped, DW_AT_prototyped) \
+ ONE_KNOWN_DW_AT (pure, DW_AT_pure) \
+ ONE_KNOWN_DW_AT (ranges, DW_AT_ranges) \
+ ONE_KNOWN_DW_AT (recursive, DW_AT_recursive) \
+ ONE_KNOWN_DW_AT (return_addr, DW_AT_return_addr) \
+ ONE_KNOWN_DW_AT (segment, DW_AT_segment) \
+ ONE_KNOWN_DW_AT (sf_names, DW_AT_sf_names) \
+ ONE_KNOWN_DW_AT (sibling, DW_AT_sibling) \
+ ONE_KNOWN_DW_AT (signature, DW_AT_signature) \
+ ONE_KNOWN_DW_AT (small, DW_AT_small) \
+ ONE_KNOWN_DW_AT (specification, DW_AT_specification) \
+ ONE_KNOWN_DW_AT (src_coords, DW_AT_src_coords) \
+ ONE_KNOWN_DW_AT (src_info, DW_AT_src_info) \
+ ONE_KNOWN_DW_AT (start_scope, DW_AT_start_scope) \
+ ONE_KNOWN_DW_AT (static_link, DW_AT_static_link) \
+ ONE_KNOWN_DW_AT (stmt_list, DW_AT_stmt_list) \
+ ONE_KNOWN_DW_AT (string_length, DW_AT_string_length) \
+ ONE_KNOWN_DW_AT (subscr_data, DW_AT_subscr_data) \
+ ONE_KNOWN_DW_AT (threads_scaled, DW_AT_threads_scaled) \
+ ONE_KNOWN_DW_AT (trampoline, DW_AT_trampoline) \
+ ONE_KNOWN_DW_AT (type, DW_AT_type) \
+ ONE_KNOWN_DW_AT (upper_bound, DW_AT_upper_bound) \
+ ONE_KNOWN_DW_AT (use_UTF8, DW_AT_use_UTF8) \
+ ONE_KNOWN_DW_AT (use_location, DW_AT_use_location) \
+ ONE_KNOWN_DW_AT (variable_parameter, DW_AT_variable_parameter) \
+ ONE_KNOWN_DW_AT (virtuality, DW_AT_virtuality) \
+ ONE_KNOWN_DW_AT (visibility, DW_AT_visibility) \
+ ONE_KNOWN_DW_AT (vtable_elem_location, DW_AT_vtable_elem_location) \
+ /* End of DW_AT_*. */
+
+#define ALL_KNOWN_DW_ATE \
+ ONE_KNOWN_DW_ATE (UTF, DW_ATE_UTF) \
+ ONE_KNOWN_DW_ATE (address, DW_ATE_address) \
+ ONE_KNOWN_DW_ATE (boolean, DW_ATE_boolean) \
+ ONE_KNOWN_DW_ATE (complex_float, DW_ATE_complex_float) \
+ ONE_KNOWN_DW_ATE (decimal_float, DW_ATE_decimal_float) \
+ ONE_KNOWN_DW_ATE (edited, DW_ATE_edited) \
+ ONE_KNOWN_DW_ATE (float, DW_ATE_float) \
+ ONE_KNOWN_DW_ATE (imaginary_float, DW_ATE_imaginary_float) \
+ ONE_KNOWN_DW_ATE (numeric_string, DW_ATE_numeric_string) \
+ ONE_KNOWN_DW_ATE (packed_decimal, DW_ATE_packed_decimal) \
+ ONE_KNOWN_DW_ATE (signed, DW_ATE_signed) \
+ ONE_KNOWN_DW_ATE (signed_char, DW_ATE_signed_char) \
+ ONE_KNOWN_DW_ATE (signed_fixed, DW_ATE_signed_fixed) \
+ ONE_KNOWN_DW_ATE (unsigned, DW_ATE_unsigned) \
+ ONE_KNOWN_DW_ATE (unsigned_char, DW_ATE_unsigned_char) \
+ ONE_KNOWN_DW_ATE (unsigned_fixed, DW_ATE_unsigned_fixed) \
+ ONE_KNOWN_DW_ATE (void, DW_ATE_void) \
+ /* End of DW_ATE_*. */
+
+#define ALL_KNOWN_DW_CC \
+ ONE_KNOWN_DW_CC (nocall, DW_CC_nocall) \
+ ONE_KNOWN_DW_CC (normal, DW_CC_normal) \
+ ONE_KNOWN_DW_CC (program, DW_CC_program) \
+ /* End of DW_CC_*. */
+
+#define ALL_KNOWN_DW_CFA \
+ ONE_KNOWN_DW_CFA (GNU_args_size, DW_CFA_GNU_args_size) \
+ ONE_KNOWN_DW_CFA (GNU_negative_offset_extended, DW_CFA_GNU_negative_offset_extended) \
+ ONE_KNOWN_DW_CFA (GNU_window_save, DW_CFA_GNU_window_save) \
+ ONE_KNOWN_DW_CFA (MIPS_advance_loc8, DW_CFA_MIPS_advance_loc8) \
+ ONE_KNOWN_DW_CFA (advance_loc, DW_CFA_advance_loc) \
+ ONE_KNOWN_DW_CFA (advance_loc1, DW_CFA_advance_loc1) \
+ ONE_KNOWN_DW_CFA (advance_loc2, DW_CFA_advance_loc2) \
+ ONE_KNOWN_DW_CFA (advance_loc4, DW_CFA_advance_loc4) \
+ ONE_KNOWN_DW_CFA (def_cfa, DW_CFA_def_cfa) \
+ ONE_KNOWN_DW_CFA (def_cfa_expression, DW_CFA_def_cfa_expression) \
+ ONE_KNOWN_DW_CFA (def_cfa_offset, DW_CFA_def_cfa_offset) \
+ ONE_KNOWN_DW_CFA (def_cfa_offset_sf, DW_CFA_def_cfa_offset_sf) \
+ ONE_KNOWN_DW_CFA (def_cfa_register, DW_CFA_def_cfa_register) \
+ ONE_KNOWN_DW_CFA (def_cfa_sf, DW_CFA_def_cfa_sf) \
+ ONE_KNOWN_DW_CFA (expression, DW_CFA_expression) \
+ ONE_KNOWN_DW_CFA (extended, DW_CFA_extended) \
+ ONE_KNOWN_DW_CFA (nop, DW_CFA_nop) \
+ ONE_KNOWN_DW_CFA (offset, DW_CFA_offset) \
+ ONE_KNOWN_DW_CFA (offset_extended, DW_CFA_offset_extended) \
+ ONE_KNOWN_DW_CFA (offset_extended_sf, DW_CFA_offset_extended_sf) \
+ ONE_KNOWN_DW_CFA (register, DW_CFA_register) \
+ ONE_KNOWN_DW_CFA (remember_state, DW_CFA_remember_state) \
+ ONE_KNOWN_DW_CFA (restore, DW_CFA_restore) \
+ ONE_KNOWN_DW_CFA (restore_extended, DW_CFA_restore_extended) \
+ ONE_KNOWN_DW_CFA (restore_state, DW_CFA_restore_state) \
+ ONE_KNOWN_DW_CFA (same_value, DW_CFA_same_value) \
+ ONE_KNOWN_DW_CFA (set_loc, DW_CFA_set_loc) \
+ ONE_KNOWN_DW_CFA (undefined, DW_CFA_undefined) \
+ ONE_KNOWN_DW_CFA (val_expression, DW_CFA_val_expression) \
+ ONE_KNOWN_DW_CFA (val_offset, DW_CFA_val_offset) \
+ ONE_KNOWN_DW_CFA (val_offset_sf, DW_CFA_val_offset_sf) \
+ /* End of DW_CFA_*. */
+
+#define ALL_KNOWN_DW_CHILDREN \
+ ONE_KNOWN_DW_CHILDREN (no, DW_CHILDREN_no) \
+ ONE_KNOWN_DW_CHILDREN (yes, DW_CHILDREN_yes) \
+ /* End of DW_CHILDREN_*. */
+
+#define ALL_KNOWN_DW_CIE_ID \
+ ONE_KNOWN_DW_CIE_ID_DESC (32, DW_CIE_ID_32, "In 32-bit format CIE header.") \
+ ONE_KNOWN_DW_CIE_ID_DESC (64, DW_CIE_ID_64, "In 64-bit format CIE header.") \
+ /* End of DW_CIE_ID_*. */
+
+#define ALL_KNOWN_DW_DS \
+ ONE_KNOWN_DW_DS (leading_overpunch, DW_DS_leading_overpunch) \
+ ONE_KNOWN_DW_DS (leading_separate, DW_DS_leading_separate) \
+ ONE_KNOWN_DW_DS (trailing_overpunch, DW_DS_trailing_overpunch) \
+ ONE_KNOWN_DW_DS (trailing_separate, DW_DS_trailing_separate) \
+ ONE_KNOWN_DW_DS (unsigned, DW_DS_unsigned) \
+ /* End of DW_DS_*. */
+
+#define ALL_KNOWN_DW_DSC \
+ ONE_KNOWN_DW_DSC (label, DW_DSC_label) \
+ ONE_KNOWN_DW_DSC (range, DW_DSC_range) \
+ /* End of DW_DSC_*. */
+
+#define ALL_KNOWN_DW_EH_PE \
+ ONE_KNOWN_DW_EH_PE (absptr, DW_EH_PE_absptr) \
+ ONE_KNOWN_DW_EH_PE (aligned, DW_EH_PE_aligned) \
+ ONE_KNOWN_DW_EH_PE (datarel, DW_EH_PE_datarel) \
+ ONE_KNOWN_DW_EH_PE (funcrel, DW_EH_PE_funcrel) \
+ ONE_KNOWN_DW_EH_PE (indirect, DW_EH_PE_indirect) \
+ ONE_KNOWN_DW_EH_PE (omit, DW_EH_PE_omit) \
+ ONE_KNOWN_DW_EH_PE (pcrel, DW_EH_PE_pcrel) \
+ ONE_KNOWN_DW_EH_PE (sdata2, DW_EH_PE_sdata2) \
+ ONE_KNOWN_DW_EH_PE (sdata4, DW_EH_PE_sdata4) \
+ ONE_KNOWN_DW_EH_PE (sdata8, DW_EH_PE_sdata8) \
+ ONE_KNOWN_DW_EH_PE (signed, DW_EH_PE_signed) \
+ ONE_KNOWN_DW_EH_PE (sleb128, DW_EH_PE_sleb128) \
+ ONE_KNOWN_DW_EH_PE (textrel, DW_EH_PE_textrel) \
+ ONE_KNOWN_DW_EH_PE (udata2, DW_EH_PE_udata2) \
+ ONE_KNOWN_DW_EH_PE (udata4, DW_EH_PE_udata4) \
+ ONE_KNOWN_DW_EH_PE (udata8, DW_EH_PE_udata8) \
+ ONE_KNOWN_DW_EH_PE (uleb128, DW_EH_PE_uleb128) \
+ /* End of DW_EH_PE_*. */
+
+#define ALL_KNOWN_DW_END \
+ ONE_KNOWN_DW_END (big, DW_END_big) \
+ ONE_KNOWN_DW_END (default, DW_END_default) \
+ ONE_KNOWN_DW_END (little, DW_END_little) \
+ /* End of DW_END_*. */
+
+#define ALL_KNOWN_DW_FORM \
+ ONE_KNOWN_DW_FORM_DESC (GNU_ref_alt, DW_FORM_GNU_ref_alt, "offset in alternate .debuginfo.") \
+ ONE_KNOWN_DW_FORM_DESC (GNU_strp_alt, DW_FORM_GNU_strp_alt, "offset in alternate .debug_str.") \
+ ONE_KNOWN_DW_FORM (addr, DW_FORM_addr) \
+ ONE_KNOWN_DW_FORM (block, DW_FORM_block) \
+ ONE_KNOWN_DW_FORM (block1, DW_FORM_block1) \
+ ONE_KNOWN_DW_FORM (block2, DW_FORM_block2) \
+ ONE_KNOWN_DW_FORM (block4, DW_FORM_block4) \
+ ONE_KNOWN_DW_FORM (data1, DW_FORM_data1) \
+ ONE_KNOWN_DW_FORM (data2, DW_FORM_data2) \
+ ONE_KNOWN_DW_FORM (data4, DW_FORM_data4) \
+ ONE_KNOWN_DW_FORM (data8, DW_FORM_data8) \
+ ONE_KNOWN_DW_FORM (exprloc, DW_FORM_exprloc) \
+ ONE_KNOWN_DW_FORM (flag, DW_FORM_flag) \
+ ONE_KNOWN_DW_FORM (flag_present, DW_FORM_flag_present) \
+ ONE_KNOWN_DW_FORM (indirect, DW_FORM_indirect) \
+ ONE_KNOWN_DW_FORM (ref1, DW_FORM_ref1) \
+ ONE_KNOWN_DW_FORM (ref2, DW_FORM_ref2) \
+ ONE_KNOWN_DW_FORM (ref4, DW_FORM_ref4) \
+ ONE_KNOWN_DW_FORM (ref8, DW_FORM_ref8) \
+ ONE_KNOWN_DW_FORM (ref_addr, DW_FORM_ref_addr) \
+ ONE_KNOWN_DW_FORM (ref_sig8, DW_FORM_ref_sig8) \
+ ONE_KNOWN_DW_FORM (ref_udata, DW_FORM_ref_udata) \
+ ONE_KNOWN_DW_FORM (sdata, DW_FORM_sdata) \
+ ONE_KNOWN_DW_FORM (sec_offset, DW_FORM_sec_offset) \
+ ONE_KNOWN_DW_FORM (string, DW_FORM_string) \
+ ONE_KNOWN_DW_FORM (strp, DW_FORM_strp) \
+ ONE_KNOWN_DW_FORM (udata, DW_FORM_udata) \
+ /* End of DW_FORM_*. */
+
+#define ALL_KNOWN_DW_ID \
+ ONE_KNOWN_DW_ID (case_insensitive, DW_ID_case_insensitive) \
+ ONE_KNOWN_DW_ID (case_sensitive, DW_ID_case_sensitive) \
+ ONE_KNOWN_DW_ID (down_case, DW_ID_down_case) \
+ ONE_KNOWN_DW_ID (up_case, DW_ID_up_case) \
+ /* End of DW_ID_*. */
+
+#define ALL_KNOWN_DW_INL \
+ ONE_KNOWN_DW_INL (declared_inlined, DW_INL_declared_inlined) \
+ ONE_KNOWN_DW_INL (declared_not_inlined, DW_INL_declared_not_inlined) \
+ ONE_KNOWN_DW_INL (inlined, DW_INL_inlined) \
+ ONE_KNOWN_DW_INL (not_inlined, DW_INL_not_inlined) \
+ /* End of DW_INL_*. */
+
+#define ALL_KNOWN_DW_LANG \
+ ONE_KNOWN_DW_LANG_DESC (Ada83, DW_LANG_Ada83, "ISO Ada:1983") \
+ ONE_KNOWN_DW_LANG_DESC (Ada95, DW_LANG_Ada95, "ISO Ada:1995") \
+ ONE_KNOWN_DW_LANG_DESC (C, DW_LANG_C, "C") \
+ ONE_KNOWN_DW_LANG_DESC (C11, DW_LANG_C11, "ISO C:2011") \
+ ONE_KNOWN_DW_LANG_DESC (C89, DW_LANG_C89, "ISO C:1989") \
+ ONE_KNOWN_DW_LANG_DESC (C99, DW_LANG_C99, "ISO C:1999") \
+ ONE_KNOWN_DW_LANG_DESC (C_plus_plus, DW_LANG_C_plus_plus, "ISO C++:1998") \
+ ONE_KNOWN_DW_LANG_DESC (C_plus_plus_11, DW_LANG_C_plus_plus_11, "ISO C++:2011") \
+ ONE_KNOWN_DW_LANG_DESC (C_plus_plus_14, DW_LANG_C_plus_plus_14, "ISO C++:2014") \
+ ONE_KNOWN_DW_LANG_DESC (Cobol74, DW_LANG_Cobol74, "ISO Cobol:1974") \
+ ONE_KNOWN_DW_LANG_DESC (Cobol85, DW_LANG_Cobol85, "ISO Cobol:1985") \
+ ONE_KNOWN_DW_LANG_DESC (D, DW_LANG_D, "D") \
+ ONE_KNOWN_DW_LANG_DESC (Fortran77, DW_LANG_Fortran77, "ISO FORTRAN 77") \
+ ONE_KNOWN_DW_LANG_DESC (Fortran90, DW_LANG_Fortran90, "ISO Fortran 90") \
+ ONE_KNOWN_DW_LANG_DESC (Fortran95, DW_LANG_Fortran95, "ISO Fortran 95") \
+ ONE_KNOWN_DW_LANG_DESC (Go, DW_LANG_Go, "Go") \
+ ONE_KNOWN_DW_LANG_DESC (Java, DW_LANG_Java, "Java") \
+ ONE_KNOWN_DW_LANG_DESC (Mips_Assembler, DW_LANG_Mips_Assembler, "Assembler") \
+ ONE_KNOWN_DW_LANG_DESC (Modula2, DW_LANG_Modula2, "ISO Modula-2:1996") \
+ ONE_KNOWN_DW_LANG_DESC (ObjC, DW_LANG_ObjC, "Objective-C") \
+ ONE_KNOWN_DW_LANG_DESC (ObjC_plus_plus, DW_LANG_ObjC_plus_plus, "Objective-C++") \
+ ONE_KNOWN_DW_LANG_DESC (PL1, DW_LANG_PL1, "ISO PL/1:1976") \
+ ONE_KNOWN_DW_LANG_DESC (Pascal83, DW_LANG_Pascal83, "ISO Pascal:1983") \
+ ONE_KNOWN_DW_LANG_DESC (Python, DW_LANG_Python, "Python") \
+ ONE_KNOWN_DW_LANG_DESC (UPC, DW_LANG_UPC, "Unified Parallel C") \
+ /* End of DW_LANG_*. */
+
+#define ALL_KNOWN_DW_LNE \
+ ONE_KNOWN_DW_LNE (define_file, DW_LNE_define_file) \
+ ONE_KNOWN_DW_LNE (end_sequence, DW_LNE_end_sequence) \
+ ONE_KNOWN_DW_LNE (set_address, DW_LNE_set_address) \
+ ONE_KNOWN_DW_LNE (set_discriminator, DW_LNE_set_discriminator) \
+ /* End of DW_LNE_*. */
+
+#define ALL_KNOWN_DW_LNS \
+ ONE_KNOWN_DW_LNS (advance_line, DW_LNS_advance_line) \
+ ONE_KNOWN_DW_LNS (advance_pc, DW_LNS_advance_pc) \
+ ONE_KNOWN_DW_LNS (const_add_pc, DW_LNS_const_add_pc) \
+ ONE_KNOWN_DW_LNS (copy, DW_LNS_copy) \
+ ONE_KNOWN_DW_LNS (fixed_advance_pc, DW_LNS_fixed_advance_pc) \
+ ONE_KNOWN_DW_LNS (negate_stmt, DW_LNS_negate_stmt) \
+ ONE_KNOWN_DW_LNS (set_basic_block, DW_LNS_set_basic_block) \
+ ONE_KNOWN_DW_LNS (set_column, DW_LNS_set_column) \
+ ONE_KNOWN_DW_LNS (set_epilogue_begin, DW_LNS_set_epilogue_begin) \
+ ONE_KNOWN_DW_LNS (set_file, DW_LNS_set_file) \
+ ONE_KNOWN_DW_LNS (set_isa, DW_LNS_set_isa) \
+ ONE_KNOWN_DW_LNS (set_prologue_end, DW_LNS_set_prologue_end) \
+ /* End of DW_LNS_*. */
+
+#define ALL_KNOWN_DW_MACINFO \
+ ONE_KNOWN_DW_MACINFO (define, DW_MACINFO_define) \
+ ONE_KNOWN_DW_MACINFO (end_file, DW_MACINFO_end_file) \
+ ONE_KNOWN_DW_MACINFO (start_file, DW_MACINFO_start_file) \
+ ONE_KNOWN_DW_MACINFO (undef, DW_MACINFO_undef) \
+ ONE_KNOWN_DW_MACINFO (vendor_ext, DW_MACINFO_vendor_ext) \
+ /* End of DW_MACINFO_*. */
+
+#define ALL_KNOWN_DW_MACRO_GNU \
+ ONE_KNOWN_DW_MACRO_GNU (define, DW_MACRO_GNU_define) \
+ ONE_KNOWN_DW_MACRO_GNU (define_indirect, DW_MACRO_GNU_define_indirect) \
+ ONE_KNOWN_DW_MACRO_GNU (end_file, DW_MACRO_GNU_end_file) \
+ ONE_KNOWN_DW_MACRO_GNU (start_file, DW_MACRO_GNU_start_file) \
+ ONE_KNOWN_DW_MACRO_GNU (transparent_include, DW_MACRO_GNU_transparent_include) \
+ ONE_KNOWN_DW_MACRO_GNU (undef, DW_MACRO_GNU_undef) \
+ ONE_KNOWN_DW_MACRO_GNU (undef_indirect, DW_MACRO_GNU_undef_indirect) \
+ /* End of DW_MACRO_GNU_*. */
+
+#define ALL_KNOWN_DW_OP \
+ ONE_KNOWN_DW_OP (GNU_const_type, DW_OP_GNU_const_type) \
+ ONE_KNOWN_DW_OP (GNU_convert, DW_OP_GNU_convert) \
+ ONE_KNOWN_DW_OP (GNU_deref_type, DW_OP_GNU_deref_type) \
+ ONE_KNOWN_DW_OP (GNU_encoded_addr, DW_OP_GNU_encoded_addr) \
+ ONE_KNOWN_DW_OP (GNU_entry_value, DW_OP_GNU_entry_value) \
+ ONE_KNOWN_DW_OP (GNU_implicit_pointer, DW_OP_GNU_implicit_pointer) \
+ ONE_KNOWN_DW_OP (GNU_parameter_ref, DW_OP_GNU_parameter_ref) \
+ ONE_KNOWN_DW_OP (GNU_push_tls_address, DW_OP_GNU_push_tls_address) \
+ ONE_KNOWN_DW_OP (GNU_regval_type, DW_OP_GNU_regval_type) \
+ ONE_KNOWN_DW_OP (GNU_reinterpret, DW_OP_GNU_reinterpret) \
+ ONE_KNOWN_DW_OP (GNU_uninit, DW_OP_GNU_uninit) \
+ ONE_KNOWN_DW_OP (abs, DW_OP_abs) \
+ ONE_KNOWN_DW_OP_DESC (addr, DW_OP_addr, "Constant address.") \
+ ONE_KNOWN_DW_OP (and, DW_OP_and) \
+ ONE_KNOWN_DW_OP_DESC (bit_piece, DW_OP_bit_piece, "ULEB128 size and ULEB128 offset in bits.") \
+ ONE_KNOWN_DW_OP_DESC (bra, DW_OP_bra, "Signed 2-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (breg0, DW_OP_breg0, "Base register 0.") \
+ ONE_KNOWN_DW_OP_DESC (breg1, DW_OP_breg1, "Base register 1.") \
+ ONE_KNOWN_DW_OP_DESC (breg10, DW_OP_breg10, "Base register 10.") \
+ ONE_KNOWN_DW_OP_DESC (breg11, DW_OP_breg11, "Base register 11.") \
+ ONE_KNOWN_DW_OP_DESC (breg12, DW_OP_breg12, "Base register 12.") \
+ ONE_KNOWN_DW_OP_DESC (breg13, DW_OP_breg13, "Base register 13.") \
+ ONE_KNOWN_DW_OP_DESC (breg14, DW_OP_breg14, "Base register 14.") \
+ ONE_KNOWN_DW_OP_DESC (breg15, DW_OP_breg15, "Base register 15.") \
+ ONE_KNOWN_DW_OP_DESC (breg16, DW_OP_breg16, "Base register 16.") \
+ ONE_KNOWN_DW_OP_DESC (breg17, DW_OP_breg17, "Base register 17.") \
+ ONE_KNOWN_DW_OP_DESC (breg18, DW_OP_breg18, "Base register 18.") \
+ ONE_KNOWN_DW_OP_DESC (breg19, DW_OP_breg19, "Base register 19.") \
+ ONE_KNOWN_DW_OP_DESC (breg2, DW_OP_breg2, "Base register 2.") \
+ ONE_KNOWN_DW_OP_DESC (breg20, DW_OP_breg20, "Base register 20.") \
+ ONE_KNOWN_DW_OP_DESC (breg21, DW_OP_breg21, "Base register 21.") \
+ ONE_KNOWN_DW_OP_DESC (breg22, DW_OP_breg22, "Base register 22.") \
+ ONE_KNOWN_DW_OP_DESC (breg23, DW_OP_breg23, "Base register 23.") \
+ ONE_KNOWN_DW_OP_DESC (breg24, DW_OP_breg24, "Base register 24.") \
+ ONE_KNOWN_DW_OP_DESC (breg25, DW_OP_breg25, "Base register 25.") \
+ ONE_KNOWN_DW_OP_DESC (breg26, DW_OP_breg26, "Base register 26.") \
+ ONE_KNOWN_DW_OP_DESC (breg27, DW_OP_breg27, "Base register 27.") \
+ ONE_KNOWN_DW_OP_DESC (breg28, DW_OP_breg28, "Base register 28.") \
+ ONE_KNOWN_DW_OP_DESC (breg29, DW_OP_breg29, "Base register 29.") \
+ ONE_KNOWN_DW_OP_DESC (breg3, DW_OP_breg3, "Base register 3.") \
+ ONE_KNOWN_DW_OP_DESC (breg30, DW_OP_breg30, "Base register 30.") \
+ ONE_KNOWN_DW_OP_DESC (breg31, DW_OP_breg31, "Base register 31.") \
+ ONE_KNOWN_DW_OP_DESC (breg4, DW_OP_breg4, "Base register 4.") \
+ ONE_KNOWN_DW_OP_DESC (breg5, DW_OP_breg5, "Base register 5.") \
+ ONE_KNOWN_DW_OP_DESC (breg6, DW_OP_breg6, "Base register 6.") \
+ ONE_KNOWN_DW_OP_DESC (breg7, DW_OP_breg7, "Base register 7.") \
+ ONE_KNOWN_DW_OP_DESC (breg8, DW_OP_breg8, "Base register 8.") \
+ ONE_KNOWN_DW_OP_DESC (breg9, DW_OP_breg9, "Base register 9.") \
+ ONE_KNOWN_DW_OP_DESC (bregx, DW_OP_bregx, "ULEB128 register followed by SLEB128 off.") \
+ ONE_KNOWN_DW_OP (call2, DW_OP_call2) \
+ ONE_KNOWN_DW_OP (call4, DW_OP_call4) \
+ ONE_KNOWN_DW_OP (call_frame_cfa, DW_OP_call_frame_cfa) \
+ ONE_KNOWN_DW_OP (call_ref, DW_OP_call_ref) \
+ ONE_KNOWN_DW_OP_DESC (const1s, DW_OP_const1s, "Signed 1-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const1u, DW_OP_const1u, "Unsigned 1-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const2s, DW_OP_const2s, "Signed 2-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const2u, DW_OP_const2u, "Unsigned 2-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const4s, DW_OP_const4s, "Signed 4-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const4u, DW_OP_const4u, "Unsigned 4-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const8s, DW_OP_const8s, "Signed 8-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (const8u, DW_OP_const8u, "Unsigned 8-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (consts, DW_OP_consts, "Signed LEB128 constant.") \
+ ONE_KNOWN_DW_OP_DESC (constu, DW_OP_constu, "Unsigned LEB128 constant.") \
+ ONE_KNOWN_DW_OP (deref, DW_OP_deref) \
+ ONE_KNOWN_DW_OP_DESC (deref_size, DW_OP_deref_size, "1-byte size of data retrieved.") \
+ ONE_KNOWN_DW_OP (div, DW_OP_div) \
+ ONE_KNOWN_DW_OP (drop, DW_OP_drop) \
+ ONE_KNOWN_DW_OP (dup, DW_OP_dup) \
+ ONE_KNOWN_DW_OP (eq, DW_OP_eq) \
+ ONE_KNOWN_DW_OP_DESC (fbreg, DW_OP_fbreg, "Signed LEB128 offset.") \
+ ONE_KNOWN_DW_OP (form_tls_address, DW_OP_form_tls_address) \
+ ONE_KNOWN_DW_OP (ge, DW_OP_ge) \
+ ONE_KNOWN_DW_OP (gt, DW_OP_gt) \
+ ONE_KNOWN_DW_OP_DESC (implicit_value, DW_OP_implicit_value, "DW_FORM_block follows opcode.") \
+ ONE_KNOWN_DW_OP (le, DW_OP_le) \
+ ONE_KNOWN_DW_OP_DESC (lit0, DW_OP_lit0, "Literal 0.") \
+ ONE_KNOWN_DW_OP_DESC (lit1, DW_OP_lit1, "Literal 1.") \
+ ONE_KNOWN_DW_OP_DESC (lit10, DW_OP_lit10, "Literal 10.") \
+ ONE_KNOWN_DW_OP_DESC (lit11, DW_OP_lit11, "Literal 11.") \
+ ONE_KNOWN_DW_OP_DESC (lit12, DW_OP_lit12, "Literal 12.") \
+ ONE_KNOWN_DW_OP_DESC (lit13, DW_OP_lit13, "Literal 13.") \
+ ONE_KNOWN_DW_OP_DESC (lit14, DW_OP_lit14, "Literal 14.") \
+ ONE_KNOWN_DW_OP_DESC (lit15, DW_OP_lit15, "Literal 15.") \
+ ONE_KNOWN_DW_OP_DESC (lit16, DW_OP_lit16, "Literal 16.") \
+ ONE_KNOWN_DW_OP_DESC (lit17, DW_OP_lit17, "Literal 17.") \
+ ONE_KNOWN_DW_OP_DESC (lit18, DW_OP_lit18, "Literal 18.") \
+ ONE_KNOWN_DW_OP_DESC (lit19, DW_OP_lit19, "Literal 19.") \
+ ONE_KNOWN_DW_OP_DESC (lit2, DW_OP_lit2, "Literal 2.") \
+ ONE_KNOWN_DW_OP_DESC (lit20, DW_OP_lit20, "Literal 20.") \
+ ONE_KNOWN_DW_OP_DESC (lit21, DW_OP_lit21, "Literal 21.") \
+ ONE_KNOWN_DW_OP_DESC (lit22, DW_OP_lit22, "Literal 22.") \
+ ONE_KNOWN_DW_OP_DESC (lit23, DW_OP_lit23, "Literal 23.") \
+ ONE_KNOWN_DW_OP_DESC (lit24, DW_OP_lit24, "Literal 24.") \
+ ONE_KNOWN_DW_OP_DESC (lit25, DW_OP_lit25, "Literal 25.") \
+ ONE_KNOWN_DW_OP_DESC (lit26, DW_OP_lit26, "Literal 26.") \
+ ONE_KNOWN_DW_OP_DESC (lit27, DW_OP_lit27, "Literal 27.") \
+ ONE_KNOWN_DW_OP_DESC (lit28, DW_OP_lit28, "Literal 28.") \
+ ONE_KNOWN_DW_OP_DESC (lit29, DW_OP_lit29, "Literal 29.") \
+ ONE_KNOWN_DW_OP_DESC (lit3, DW_OP_lit3, "Literal 3.") \
+ ONE_KNOWN_DW_OP_DESC (lit30, DW_OP_lit30, "Literal 30.") \
+ ONE_KNOWN_DW_OP_DESC (lit31, DW_OP_lit31, "Literal 31.") \
+ ONE_KNOWN_DW_OP_DESC (lit4, DW_OP_lit4, "Literal 4.") \
+ ONE_KNOWN_DW_OP_DESC (lit5, DW_OP_lit5, "Literal 5.") \
+ ONE_KNOWN_DW_OP_DESC (lit6, DW_OP_lit6, "Literal 6.") \
+ ONE_KNOWN_DW_OP_DESC (lit7, DW_OP_lit7, "Literal 7.") \
+ ONE_KNOWN_DW_OP_DESC (lit8, DW_OP_lit8, "Literal 8.") \
+ ONE_KNOWN_DW_OP_DESC (lit9, DW_OP_lit9, "Literal 9.") \
+ ONE_KNOWN_DW_OP (lt, DW_OP_lt) \
+ ONE_KNOWN_DW_OP (minus, DW_OP_minus) \
+ ONE_KNOWN_DW_OP (mod, DW_OP_mod) \
+ ONE_KNOWN_DW_OP (mul, DW_OP_mul) \
+ ONE_KNOWN_DW_OP (ne, DW_OP_ne) \
+ ONE_KNOWN_DW_OP (neg, DW_OP_neg) \
+ ONE_KNOWN_DW_OP (nop, DW_OP_nop) \
+ ONE_KNOWN_DW_OP (not, DW_OP_not) \
+ ONE_KNOWN_DW_OP (or, DW_OP_or) \
+ ONE_KNOWN_DW_OP (over, DW_OP_over) \
+ ONE_KNOWN_DW_OP_DESC (pick, DW_OP_pick, "1-byte stack index.") \
+ ONE_KNOWN_DW_OP_DESC (piece, DW_OP_piece, "ULEB128 size of piece addressed.") \
+ ONE_KNOWN_DW_OP (plus, DW_OP_plus) \
+ ONE_KNOWN_DW_OP_DESC (plus_uconst, DW_OP_plus_uconst, "Unsigned LEB128 addend.") \
+ ONE_KNOWN_DW_OP (push_object_address, DW_OP_push_object_address) \
+ ONE_KNOWN_DW_OP_DESC (reg0, DW_OP_reg0, "Register 0.") \
+ ONE_KNOWN_DW_OP_DESC (reg1, DW_OP_reg1, "Register 1.") \
+ ONE_KNOWN_DW_OP_DESC (reg10, DW_OP_reg10, "Register 10.") \
+ ONE_KNOWN_DW_OP_DESC (reg11, DW_OP_reg11, "Register 11.") \
+ ONE_KNOWN_DW_OP_DESC (reg12, DW_OP_reg12, "Register 12.") \
+ ONE_KNOWN_DW_OP_DESC (reg13, DW_OP_reg13, "Register 13.") \
+ ONE_KNOWN_DW_OP_DESC (reg14, DW_OP_reg14, "Register 14.") \
+ ONE_KNOWN_DW_OP_DESC (reg15, DW_OP_reg15, "Register 15.") \
+ ONE_KNOWN_DW_OP_DESC (reg16, DW_OP_reg16, "Register 16.") \
+ ONE_KNOWN_DW_OP_DESC (reg17, DW_OP_reg17, "Register 17.") \
+ ONE_KNOWN_DW_OP_DESC (reg18, DW_OP_reg18, "Register 18.") \
+ ONE_KNOWN_DW_OP_DESC (reg19, DW_OP_reg19, "Register 19.") \
+ ONE_KNOWN_DW_OP_DESC (reg2, DW_OP_reg2, "Register 2.") \
+ ONE_KNOWN_DW_OP_DESC (reg20, DW_OP_reg20, "Register 20.") \
+ ONE_KNOWN_DW_OP_DESC (reg21, DW_OP_reg21, "Register 21.") \
+ ONE_KNOWN_DW_OP_DESC (reg22, DW_OP_reg22, "Register 22.") \
+ ONE_KNOWN_DW_OP_DESC (reg23, DW_OP_reg23, "Register 24.") \
+ ONE_KNOWN_DW_OP_DESC (reg24, DW_OP_reg24, "Register 24.") \
+ ONE_KNOWN_DW_OP_DESC (reg25, DW_OP_reg25, "Register 25.") \
+ ONE_KNOWN_DW_OP_DESC (reg26, DW_OP_reg26, "Register 26.") \
+ ONE_KNOWN_DW_OP_DESC (reg27, DW_OP_reg27, "Register 27.") \
+ ONE_KNOWN_DW_OP_DESC (reg28, DW_OP_reg28, "Register 28.") \
+ ONE_KNOWN_DW_OP_DESC (reg29, DW_OP_reg29, "Register 29.") \
+ ONE_KNOWN_DW_OP_DESC (reg3, DW_OP_reg3, "Register 3.") \
+ ONE_KNOWN_DW_OP_DESC (reg30, DW_OP_reg30, "Register 30.") \
+ ONE_KNOWN_DW_OP_DESC (reg31, DW_OP_reg31, "Register 31.") \
+ ONE_KNOWN_DW_OP_DESC (reg4, DW_OP_reg4, "Register 4.") \
+ ONE_KNOWN_DW_OP_DESC (reg5, DW_OP_reg5, "Register 5.") \
+ ONE_KNOWN_DW_OP_DESC (reg6, DW_OP_reg6, "Register 6.") \
+ ONE_KNOWN_DW_OP_DESC (reg7, DW_OP_reg7, "Register 7.") \
+ ONE_KNOWN_DW_OP_DESC (reg8, DW_OP_reg8, "Register 8.") \
+ ONE_KNOWN_DW_OP_DESC (reg9, DW_OP_reg9, "Register 9.") \
+ ONE_KNOWN_DW_OP_DESC (regx, DW_OP_regx, "Unsigned LEB128 register.") \
+ ONE_KNOWN_DW_OP (rot, DW_OP_rot) \
+ ONE_KNOWN_DW_OP (shl, DW_OP_shl) \
+ ONE_KNOWN_DW_OP (shr, DW_OP_shr) \
+ ONE_KNOWN_DW_OP (shra, DW_OP_shra) \
+ ONE_KNOWN_DW_OP_DESC (skip, DW_OP_skip, "Signed 2-byte constant.") \
+ ONE_KNOWN_DW_OP_DESC (stack_value, DW_OP_stack_value, "No operands, special like DW_OP_piece.") \
+ ONE_KNOWN_DW_OP (swap, DW_OP_swap) \
+ ONE_KNOWN_DW_OP (xderef, DW_OP_xderef) \
+ ONE_KNOWN_DW_OP_DESC (xderef_size, DW_OP_xderef_size, "1-byte size of data retrieved.") \
+ ONE_KNOWN_DW_OP (xor, DW_OP_xor) \
+ /* End of DW_OP_*. */
+
+#define ALL_KNOWN_DW_ORD \
+ ONE_KNOWN_DW_ORD (col_major, DW_ORD_col_major) \
+ ONE_KNOWN_DW_ORD (row_major, DW_ORD_row_major) \
+ /* End of DW_ORD_*. */
+
+#define ALL_KNOWN_DW_TAG \
+ ONE_KNOWN_DW_TAG (GNU_BINCL, DW_TAG_GNU_BINCL) \
+ ONE_KNOWN_DW_TAG (GNU_EINCL, DW_TAG_GNU_EINCL) \
+ ONE_KNOWN_DW_TAG (GNU_call_site, DW_TAG_GNU_call_site) \
+ ONE_KNOWN_DW_TAG (GNU_call_site_parameter, DW_TAG_GNU_call_site_parameter) \
+ ONE_KNOWN_DW_TAG (GNU_formal_parameter_pack, DW_TAG_GNU_formal_parameter_pack) \
+ ONE_KNOWN_DW_TAG (GNU_template_parameter_pack, DW_TAG_GNU_template_parameter_pack) \
+ ONE_KNOWN_DW_TAG (GNU_template_template_param, DW_TAG_GNU_template_template_param) \
+ ONE_KNOWN_DW_TAG (MIPS_loop, DW_TAG_MIPS_loop) \
+ ONE_KNOWN_DW_TAG (access_declaration, DW_TAG_access_declaration) \
+ ONE_KNOWN_DW_TAG (array_type, DW_TAG_array_type) \
+ ONE_KNOWN_DW_TAG (base_type, DW_TAG_base_type) \
+ ONE_KNOWN_DW_TAG (catch_block, DW_TAG_catch_block) \
+ ONE_KNOWN_DW_TAG (class_template, DW_TAG_class_template) \
+ ONE_KNOWN_DW_TAG (class_type, DW_TAG_class_type) \
+ ONE_KNOWN_DW_TAG (common_block, DW_TAG_common_block) \
+ ONE_KNOWN_DW_TAG (common_inclusion, DW_TAG_common_inclusion) \
+ ONE_KNOWN_DW_TAG (compile_unit, DW_TAG_compile_unit) \
+ ONE_KNOWN_DW_TAG (condition, DW_TAG_condition) \
+ ONE_KNOWN_DW_TAG (const_type, DW_TAG_const_type) \
+ ONE_KNOWN_DW_TAG (constant, DW_TAG_constant) \
+ ONE_KNOWN_DW_TAG (dwarf_procedure, DW_TAG_dwarf_procedure) \
+ ONE_KNOWN_DW_TAG (entry_point, DW_TAG_entry_point) \
+ ONE_KNOWN_DW_TAG (enumeration_type, DW_TAG_enumeration_type) \
+ ONE_KNOWN_DW_TAG (enumerator, DW_TAG_enumerator) \
+ ONE_KNOWN_DW_TAG (file_type, DW_TAG_file_type) \
+ ONE_KNOWN_DW_TAG (formal_parameter, DW_TAG_formal_parameter) \
+ ONE_KNOWN_DW_TAG (format_label, DW_TAG_format_label) \
+ ONE_KNOWN_DW_TAG (friend, DW_TAG_friend) \
+ ONE_KNOWN_DW_TAG (function_template, DW_TAG_function_template) \
+ ONE_KNOWN_DW_TAG (imported_declaration, DW_TAG_imported_declaration) \
+ ONE_KNOWN_DW_TAG (imported_module, DW_TAG_imported_module) \
+ ONE_KNOWN_DW_TAG (imported_unit, DW_TAG_imported_unit) \
+ ONE_KNOWN_DW_TAG (inheritance, DW_TAG_inheritance) \
+ ONE_KNOWN_DW_TAG (inlined_subroutine, DW_TAG_inlined_subroutine) \
+ ONE_KNOWN_DW_TAG (interface_type, DW_TAG_interface_type) \
+ ONE_KNOWN_DW_TAG (label, DW_TAG_label) \
+ ONE_KNOWN_DW_TAG (lexical_block, DW_TAG_lexical_block) \
+ ONE_KNOWN_DW_TAG (member, DW_TAG_member) \
+ ONE_KNOWN_DW_TAG (module, DW_TAG_module) \
+ ONE_KNOWN_DW_TAG (namelist, DW_TAG_namelist) \
+ ONE_KNOWN_DW_TAG (namelist_item, DW_TAG_namelist_item) \
+ ONE_KNOWN_DW_TAG (namespace, DW_TAG_namespace) \
+ ONE_KNOWN_DW_TAG (packed_type, DW_TAG_packed_type) \
+ ONE_KNOWN_DW_TAG (partial_unit, DW_TAG_partial_unit) \
+ ONE_KNOWN_DW_TAG (pointer_type, DW_TAG_pointer_type) \
+ ONE_KNOWN_DW_TAG (ptr_to_member_type, DW_TAG_ptr_to_member_type) \
+ ONE_KNOWN_DW_TAG (reference_type, DW_TAG_reference_type) \
+ ONE_KNOWN_DW_TAG (restrict_type, DW_TAG_restrict_type) \
+ ONE_KNOWN_DW_TAG (rvalue_reference_type, DW_TAG_rvalue_reference_type) \
+ ONE_KNOWN_DW_TAG (set_type, DW_TAG_set_type) \
+ ONE_KNOWN_DW_TAG (shared_type, DW_TAG_shared_type) \
+ ONE_KNOWN_DW_TAG (string_type, DW_TAG_string_type) \
+ ONE_KNOWN_DW_TAG (structure_type, DW_TAG_structure_type) \
+ ONE_KNOWN_DW_TAG (subprogram, DW_TAG_subprogram) \
+ ONE_KNOWN_DW_TAG (subrange_type, DW_TAG_subrange_type) \
+ ONE_KNOWN_DW_TAG (subroutine_type, DW_TAG_subroutine_type) \
+ ONE_KNOWN_DW_TAG (template_alias, DW_TAG_template_alias) \
+ ONE_KNOWN_DW_TAG (template_type_parameter, DW_TAG_template_type_parameter) \
+ ONE_KNOWN_DW_TAG (template_value_parameter, DW_TAG_template_value_parameter) \
+ ONE_KNOWN_DW_TAG (thrown_type, DW_TAG_thrown_type) \
+ ONE_KNOWN_DW_TAG (try_block, DW_TAG_try_block) \
+ ONE_KNOWN_DW_TAG (type_unit, DW_TAG_type_unit) \
+ ONE_KNOWN_DW_TAG (typedef, DW_TAG_typedef) \
+ ONE_KNOWN_DW_TAG (union_type, DW_TAG_union_type) \
+ ONE_KNOWN_DW_TAG (unspecified_parameters, DW_TAG_unspecified_parameters) \
+ ONE_KNOWN_DW_TAG (unspecified_type, DW_TAG_unspecified_type) \
+ ONE_KNOWN_DW_TAG (variable, DW_TAG_variable) \
+ ONE_KNOWN_DW_TAG (variant, DW_TAG_variant) \
+ ONE_KNOWN_DW_TAG (variant_part, DW_TAG_variant_part) \
+ ONE_KNOWN_DW_TAG (volatile_type, DW_TAG_volatile_type) \
+ ONE_KNOWN_DW_TAG (with_stmt, DW_TAG_with_stmt) \
+ /* End of DW_TAG_*. */
+
+#define ALL_KNOWN_DW_VIRTUALITY \
+ ONE_KNOWN_DW_VIRTUALITY (none, DW_VIRTUALITY_none) \
+ ONE_KNOWN_DW_VIRTUALITY (pure_virtual, DW_VIRTUALITY_pure_virtual) \
+ ONE_KNOWN_DW_VIRTUALITY (virtual, DW_VIRTUALITY_virtual) \
+ /* End of DW_VIRTUALITY_*. */
+
+#define ALL_KNOWN_DW_VIS \
+ ONE_KNOWN_DW_VIS (exported, DW_VIS_exported) \
+ ONE_KNOWN_DW_VIS (local, DW_VIS_local) \
+ ONE_KNOWN_DW_VIS (qualified, DW_VIS_qualified) \
+ /* End of DW_VIS_*. */
diff --git a/3rdparty/elfutils/libdw/libdw.h b/3rdparty/elfutils/libdw/libdw.h
new file mode 100644
index 0000000..b2b2282
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdw.h
@@ -0,0 +1,1026 @@
+/* Interfaces for libdw.
+ Copyright (C) 2002-2010, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBDW_H
+#define _LIBDW_H 1
+
+#include <gelf.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__)))
+# define __deprecated_attribute__ __attribute__ ((__deprecated__))
+#else
+# define __nonnull_attribute__(args...)
+# define __deprecated_attribute__
+#endif
+
+
+#ifdef __GNUC_STDC_INLINE__
+# define __libdw_extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#else
+# define __libdw_extern_inline extern __inline
+#endif
+
+
+/* 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;
+
+#define dwarf_cfi_cie_p(entry) ((entry)->cie.CIE_id == DW_CIE_ID_64)
+
+/* 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. */
+#if __GNUC__ < 4
+typedef void (*Dwarf_OOM) (void);
+#else
+typedef void (*__attribute__ ((noreturn)) Dwarf_OOM) (void);
+#endif
+
+
+#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);
+
+/* Retieve 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. */
+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. */
+extern void dwarf_setalt (Dwarf *main, Dwarf *alt);
+
+/* Release debugging handling context. */
+extern int dwarf_end (Dwarf *dwarf);
+
+
+/* Get the data block for the .debug_info section. */
+extern Elf_Data *dwarf_getscn_info (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);
+
+
+/* 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);
+
+/* 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 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 occured.
+
+ The current DWARF specification defines one type alias tag
+ (DW_TAG_typedef) and three qualifier type tags (DW_TAG_const_type,
+ DW_TAG_volatile_type, DW_TAG_restrict_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 or change the structural
+ layout of 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. */
+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 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. */
+extern const char *dwarf_linesrc (Dwarf_Line *line,
+ Dwarf_Word *mtime, Dwarf_Word *length);
+
+/* Return file information. */
+extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx,
+ Dwarf_Word *mtime, Dwarf_Word *length);
+
+/* 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);
+
+
+/* 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);
+
+
+/* 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. */
+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. 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/3rdparty/elfutils/libdw/libdw.pro b/3rdparty/elfutils/libdw/libdw.pro
new file mode 100644
index 0000000..f31cc71
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdw.pro
@@ -0,0 +1,127 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../dw
+
+include(../elfutils.pri)
+include(../libelf/elfheaders.pri)
+include(dwheaders.pri)
+
+SOURCES += \
+ $$PWD/cfi.c \
+ $$PWD/cie.c \
+ $$PWD/dwarf_abbrev_hash.c \
+ $$PWD/dwarf_abbrevhaschildren.c \
+ $$PWD/dwarf_addrdie.c \
+ $$PWD/dwarf_aggregate_size.c \
+ $$PWD/dwarf_arrayorder.c \
+ $$PWD/dwarf_attr_integrate.c \
+ $$PWD/dwarf_attr.c \
+ $$PWD/dwarf_begin_elf.c \
+ $$PWD/dwarf_begin.c \
+ $$PWD/dwarf_bitoffset.c \
+ $$PWD/dwarf_bitsize.c \
+ $$PWD/dwarf_bytesize.c \
+ $$PWD/dwarf_cfi_addrframe.c \
+ $$PWD/dwarf_cfi_end.c \
+ $$PWD/dwarf_child.c \
+ $$PWD/dwarf_cu_die.c \
+ $$PWD/dwarf_cu_getdwarf.c \
+ $$PWD/dwarf_cuoffset.c \
+ $$PWD/dwarf_decl_column.c \
+ $$PWD/dwarf_decl_file.c \
+ $$PWD/dwarf_decl_line.c \
+ $$PWD/dwarf_diecu.c \
+ $$PWD/dwarf_diename.c \
+ $$PWD/dwarf_dieoffset.c \
+ $$PWD/dwarf_end.c \
+ $$PWD/dwarf_entry_breakpoints.c \
+ $$PWD/dwarf_entrypc.c \
+ $$PWD/dwarf_error.c \
+ $$PWD/dwarf_filesrc.c \
+ $$PWD/dwarf_formaddr.c \
+ $$PWD/dwarf_formblock.c \
+ $$PWD/dwarf_formflag.c \
+ $$PWD/dwarf_formref_die.c \
+ $$PWD/dwarf_formref.c \
+ $$PWD/dwarf_formsdata.c \
+ $$PWD/dwarf_formstring.c \
+ $$PWD/dwarf_formudata.c \
+ $$PWD/dwarf_frame_cfa.c \
+ $$PWD/dwarf_frame_info.c \
+ $$PWD/dwarf_frame_register.c \
+ $$PWD/dwarf_func_inline.c \
+ $$PWD/dwarf_getabbrev.c \
+ $$PWD/dwarf_getabbrevattr.c \
+ $$PWD/dwarf_getabbrevcode.c \
+ $$PWD/dwarf_getabbrevtag.c \
+ $$PWD/dwarf_getalt.c \
+ $$PWD/dwarf_getarange_addr.c \
+ $$PWD/dwarf_getarangeinfo.c \
+ $$PWD/dwarf_getaranges.c \
+ $$PWD/dwarf_getattrcnt.c \
+ $$PWD/dwarf_getattrs.c \
+ $$PWD/dwarf_getcfi_elf.c \
+ $$PWD/dwarf_getcfi.c \
+ $$PWD/dwarf_getelf.c \
+ $$PWD/dwarf_getfuncs.c \
+ $$PWD/dwarf_getlocation_attr.c \
+ $$PWD/dwarf_getlocation_die.c \
+ $$PWD/dwarf_getlocation_implicit_pointer.c \
+ $$PWD/dwarf_getlocation.c \
+ $$PWD/dwarf_getmacros.c \
+ $$PWD/dwarf_getpubnames.c \
+ $$PWD/dwarf_getscopes_die.c \
+ $$PWD/dwarf_getscopes.c \
+ $$PWD/dwarf_getscopevar.c \
+ $$PWD/dwarf_getsrc_die.c \
+ $$PWD/dwarf_getsrc_file.c \
+ $$PWD/dwarf_getsrcdirs.c \
+ $$PWD/dwarf_getsrcfiles.c \
+ $$PWD/dwarf_getsrclines.c \
+ $$PWD/dwarf_getstring.c \
+ $$PWD/dwarf_hasattr_integrate.c \
+ $$PWD/dwarf_hasattr.c \
+ $$PWD/dwarf_haschildren.c \
+ $$PWD/dwarf_hasform.c \
+ $$PWD/dwarf_haspc.c \
+ $$PWD/dwarf_highpc.c \
+ $$PWD/dwarf_lineaddr.c \
+ $$PWD/dwarf_linebeginstatement.c \
+ $$PWD/dwarf_lineblock.c \
+ $$PWD/dwarf_linecol.c \
+ $$PWD/dwarf_linediscriminator.c \
+ $$PWD/dwarf_lineendsequence.c \
+ $$PWD/dwarf_lineepiloguebegin.c \
+ $$PWD/dwarf_lineisa.c \
+ $$PWD/dwarf_lineno.c \
+ $$PWD/dwarf_lineop_index.c \
+ $$PWD/dwarf_lineprologueend.c \
+ $$PWD/dwarf_linesrc.c \
+ $$PWD/dwarf_lowpc.c \
+ $$PWD/dwarf_macro_getparamcnt.c \
+ $$PWD/dwarf_macro_getsrcfiles.c \
+ $$PWD/dwarf_macro_opcode.c \
+ $$PWD/dwarf_macro_param.c \
+ $$PWD/dwarf_macro_param1.c \
+ $$PWD/dwarf_macro_param2.c \
+ $$PWD/dwarf_next_cfi.c \
+ $$PWD/dwarf_nextcu.c \
+ $$PWD/dwarf_offabbrev.c \
+ $$PWD/dwarf_offdie.c \
+ $$PWD/dwarf_onearange.c \
+ $$PWD/dwarf_onesrcline.c \
+ $$PWD/dwarf_peel_type.c \
+ $$PWD/dwarf_ranges.c \
+ $$PWD/dwarf_setalt.c \
+ $$PWD/dwarf_siblingof.c \
+ $$PWD/dwarf_sig8_hash.c \
+ $$PWD/dwarf_srclang.c \
+ $$PWD/dwarf_tag.c \
+ $$PWD/dwarf_whatattr.c \
+ $$PWD/dwarf_whatform.c \
+ $$PWD/fde.c \
+ $$PWD/frame-cache.c \
+ $$PWD/libdw_alloc.c \
+ $$PWD/libdw_findcu.c \
+ $$PWD/libdw_form.c \
+ $$PWD/libdw_visit_scopes.c
diff --git a/3rdparty/elfutils/libdw/libdwP.h b/3rdparty/elfutils/libdw/libdwP.h
new file mode 100644
index 0000000..5ab7219
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdwP.h
@@ -0,0 +1,802 @@
+/* Internal definitions for libdwarf.
+ Copyright (C) 2002-2011, 2013, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBDWP_H
+#define _LIBDWP_H 1
+
+#include <libintl.h>
+#include <stdbool.h>
+
+#include <libdw.h>
+#include <dwarf.h>
+
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* 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 indeces for the section data. */
+enum
+ {
+ IDX_debug_info = 0,
+ IDX_debug_types,
+ IDX_debug_abbrev,
+ IDX_debug_aranges,
+ IDX_debug_line,
+ IDX_debug_frame,
+ IDX_debug_loc,
+ IDX_debug_pubnames,
+ IDX_debug_str,
+ IDX_debug_macinfo,
+ IDX_debug_macro,
+ IDX_debug_ranges,
+ 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_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_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_LOCLIST,
+ 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_INVALID_CFI,
+ DWARF_E_NO_ALT_DEBUGLINK,
+ DWARF_E_INVALID_OPCODE,
+};
+
+
+#include "dwarf_sig8_hash.h"
+
+/* This is the structure representing the debugging state. */
+struct Dwarf
+{
+ /* The underlying ELF file. */
+ Elf *elf;
+
+ /* dwz alternate DWARF file. */
+ Dwarf *alt_dwarf;
+
+ /* The section data. */
+ Elf_Data *sectiondata[IDX_last];
+
+#if USE_ZLIB
+ /* The 1 << N bit is set if sectiondata[N] is malloc'd decompressed data. */
+ unsigned int sectiondata_gzip_mask:IDX_last;
+#endif
+
+ /* 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;
+
+ /* 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 .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. */
+ struct Dwarf_CU *fake_loc_cu;
+
+ /* Internal memory handling. This is basically a simplified
+ reimplementation of obstacks. Unfortunately the standard obstack
+ implementation is not usable in libraries. */
+ struct libdw_memblock
+ {
+ size_t size;
+ size_t remaining;
+ struct libdw_memblock *prev;
+ char mem[0];
+ } *mem_tail;
+
+ /* 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;
+ unsigned char *attrp;
+ unsigned int attrcnt;
+ unsigned int code;
+ unsigned int tag;
+ bool has_children;
+};
+
+#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;
+
+ /* Zero if this is a normal CU. Nonzero if it is a type unit. */
+ size_t type_offset;
+ uint64_t type_sig8;
+
+ /* 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;
+
+ /* Memory boundaries of this CU. */
+ void *startp;
+ void *endp;
+};
+
+/* Compute the offset of a CU's first DIE from its offset. This
+ is either:
+ 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 *' into a '2 *'. If the
+ offset_size is 8 it accounts for the 4-byte escape value
+ used at the start of the length. */
+#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit) \
+ ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8) \
+ : ((cu_offset) + 3 * (offset_size) - 4 + 3))
+
+#define CUDIE(fromcu) \
+ ((Dwarf_Die) \
+ { \
+ .cu = (fromcu), \
+ .addr = ((char *) fromcu->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \
+ + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start, \
+ (fromcu)->offset_size, \
+ (fromcu)->type_offset != 0)) \
+ }) \
+
+
+/* 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;
+}
+
+/* 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. This macro does not do any locking. */
+#define libdw_alloc(dbg, type, tsize, cnt) \
+ ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \
+ 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)
+
+/* 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, visibility ("hidden")));
+
+#if USE_ZLIB
+extern void __libdw_free_zdata (Dwarf *dwarf) internal_function;
+#else
+# define __libdw_free_zdata(dwarf) ((void) (dwarf))
+#endif
+
+/* 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;
+
+/* 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;
+ 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. */
+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_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
+ [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
+ [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
+ [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
+ };
+
+ /* 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,
+ 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, 3) 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 - offset < 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 - (addr - data->d_buf) < 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->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
+}
+
+/* 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 *dbg, int sec_index,
+ unsigned char **addr, int width,
+ Dwarf_Addr *beginp, Dwarf_Addr *endp,
+ Dwarf_Addr *basep)
+ internal_function;
+
+unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
+ int err_nodata, 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);
+
+
+/* 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_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_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/3rdparty/elfutils/libdw/libdw_alloc.c b/3rdparty/elfutils/libdw/libdw_alloc.c
new file mode 100644
index 0000000..a3b7958
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdw_alloc.c
@@ -0,0 +1,78 @@
+/* Memory handling for libdw.
+ Copyright (C) 2003, 2004, 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include "libdwP.h"
+
+
+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);
+
+ newp->prev = dbg->mem_tail;
+ dbg->mem_tail = newp;
+
+ 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, visibility ("hidden")))
+__libdw_oom (void)
+{
+ while (1)
+ error (EXIT_FAILURE, ENOMEM, "libdw");
+}
diff --git a/3rdparty/elfutils/libdw/libdw_findcu.c b/3rdparty/elfutils/libdw/libdw_findcu.c
new file mode 100644
index 0000000..d8da2e3
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdw_findcu.c
@@ -0,0 +1,172 @@
+/* Find CU for given offset.
+ Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <search.h>
+#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;
+}
+
+struct Dwarf_CU *
+internal_function
+__libdw_intern_next_unit (dbg, debug_types)
+ 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 address_size;
+ uint8_t offset_size;
+ Dwarf_Off abbrev_offset;
+ uint64_t type_sig8 = 0;
+ Dwarf_Off type_offset = 0;
+
+ if (INTUSE(dwarf_next_unit) (dbg, oldoff, offsetp, NULL,
+ &version, &abbrev_offset,
+ &address_size, &offset_size,
+ debug_types ? &type_sig8 : NULL,
+ debug_types ? &type_offset : NULL) != 0)
+ /* No more entries. */
+ return NULL;
+
+ /* We only know how to handle the DWARF version 2 through 4 formats. */
+ if (unlikely (version < 2) || unlikely (version > 4))
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return NULL;
+ }
+
+ /* Invalid or truncated debug section data? */
+ Elf_Data *data = dbg->sectiondata[debug_types
+ ? IDX_debug_types : IDX_debug_info];
+ 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->start = oldoff;
+ newp->end = *offsetp;
+ newp->address_size = address_size;
+ newp->offset_size = offset_size;
+ newp->version = version;
+ newp->type_sig8 = type_sig8;
+ newp->type_offset = type_offset;
+ Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
+ newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
+ newp->lines = NULL;
+ newp->locs = NULL;
+
+ if (debug_types)
+ Dwarf_Sig8_Hash_insert (&dbg->sig8_hash, type_sig8, newp);
+
+ newp->startp = data->d_buf + newp->start;
+ newp->endp = data->d_buf + newp->end;
+
+ /* 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 *
+__libdw_findcu (dbg, start, debug_types)
+ Dwarf *dbg;
+ Dwarf_Off start;
+ bool debug_types;
+{
+ void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
+ Dwarf_Off *next_offset
+ = 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, debug_types);
+ if (newp == NULL)
+ return NULL;
+
+ /* Is this the one we are looking for? */
+ if (start < *next_offset)
+ // XXX Match exact offset.
+ return newp;
+ }
+ /* NOTREACHED */
+}
diff --git a/3rdparty/elfutils/libdw/libdw_form.c b/3rdparty/elfutils/libdw/libdw_form.c
new file mode 100644
index 0000000..72e2390
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdw_form.c
@@ -0,0 +1,132 @@
+/* Helper functions for form handling.
+ Copyright (C) 2003-2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <string.h>
+
+#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_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:
+ get_uleb128 (u128, valp, endp);
+ result = valp - startp;
+ break;
+
+ case DW_FORM_indirect:
+ get_uleb128 (u128, valp, endp);
+ // XXX Is this really correct?
+ 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/3rdparty/elfutils/libdw/libdw_visit_scopes.c b/3rdparty/elfutils/libdw/libdw_visit_scopes.c
new file mode 100644
index 0000000..487375d
--- /dev/null
+++ b/3rdparty/elfutils/libdw/libdw_visit_scopes.c
@@ -0,0 +1,147 @@
+/* Helper functions to descend DWARF scope trees.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+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;
+}
+
+int
+__libdw_visit_scopes (depth, root, previsit, postvisit, arg)
+ unsigned int depth;
+ struct Dwarf_Die_Chain *root;
+ int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+ int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+ void *arg;
+{
+ struct Dwarf_Die_Chain child;
+ int ret;
+
+ child.parent = root;
+ if ((ret = INTUSE(dwarf_child) (&root->die, &child.die)) != 0)
+ return ret < 0 ? -1 : 0; // Having zero children is legal.
+
+ inline int recurse (void)
+ {
+ return __libdw_visit_scopes (depth + 1, &child,
+ previsit, postvisit, arg);
+ }
+
+ inline int walk_children ()
+ {
+ 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) (&child.die) == DW_TAG_imported_unit)
+ {
+ Dwarf_Die orig_child_die = child.die;
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child.die,
+ DW_AT_import,
+ &attr_mem);
+ if (INTUSE(dwarf_formref_die) (attr, &child.die) != NULL
+ && INTUSE(dwarf_child) (&child.die, &child.die) == 0)
+ {
+ int result = walk_children ();
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+
+ /* Any "real" children left? */
+ if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die,
+ &child.die)) != 0)
+ return ret < 0 ? -1 : 0;
+ };
+
+ child.prune = false;
+
+ if (previsit != NULL)
+ {
+ int result = (*previsit) (depth + 1, &child, arg);
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+
+ if (!child.prune && may_have_scopes (&child.die)
+ && INTUSE(dwarf_haschildren) (&child.die))
+ {
+ int result = recurse ();
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+
+ if (postvisit != NULL)
+ {
+ int result = (*postvisit) (depth + 1, &child, arg);
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+ }
+ while ((ret = INTUSE(dwarf_siblingof) (&child.die, &child.die)) == 0);
+
+ return ret < 0 ? -1 : 0;
+ }
+
+ return walk_children ();
+}
diff --git a/3rdparty/elfutils/libdw/memory-access.h b/3rdparty/elfutils/libdw/memory-access.h
new file mode 100644
index 0000000..a53f791
--- /dev/null
+++ b/3rdparty/elfutils/libdw/memory-access.h
@@ -0,0 +1,272 @@
+/* Unaligned memory access functionality.
+ Copyright (C) 2000-2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _MEMORY_ACCESS_H
+#define _MEMORY_ACCESS_H 1
+
+#include <byteswap.h>
+#include <limits.h>
+#include <stdint.h>
+
+
+/* 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 unsigned char *addr, const unsigned char *end)
+{
+ const size_t type_len = len_leb128 (uint64_t);
+ const size_t pointer_len = likely (addr < end) ? end - addr : 0;
+ return likely (type_len <= pointer_len) ? type_len : pointer_len;
+}
+
+#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_leb128 (*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;
+}
+
+/* Note, addr needs to me smaller than end. */
+#define get_uleb128(var, addr, end) ((var) = __libdw_get_uleb128 (&(addr), end))
+
+/* The signed case is similar, but we sign-extend the result. */
+
+#define get_sleb128_step(var, addr, nth) \
+ do { \
+ unsigned char __b = *(addr)++; \
+ if (likely ((__b & 0x80) == 0)) \
+ { \
+ struct { signed int i:7; } __s = { .i = __b }; \
+ (var) |= (typeof (var)) __s.i * ((typeof (var)) 1 << ((nth) * 7)); \
+ return (var); \
+ } \
+ (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \
+ } while (0)
+
+static inline int64_t
+__libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end)
+{
+ int64_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_leb128 (*addrp - 1, end);
+ for (size_t i = 1; i < max; ++i)
+ get_sleb128_step (acc, *addrp, i);
+ /* 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))
+
+
+/* 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_; })
+
+
+#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/3rdparty/elfutils/libdwelf/dwelf_dwarf_gnu_debugaltlink.c b/3rdparty/elfutils/libdwelf/dwelf_dwarf_gnu_debugaltlink.c
new file mode 100644
index 0000000..b8285d0
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdwelf/dwelf_elf_gnu_build_id.c b/3rdparty/elfutils/libdwelf/dwelf_elf_gnu_build_id.c
new file mode 100644
index 0000000..1ed501d
--- /dev/null
+++ b/3rdparty/elfutils/libdwelf/dwelf_elf_gnu_build_id.c
@@ -0,0 +1,147 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwelfP.h"
+#include "libdwflP.h"
+
+#define NO_VADDR ((GElf_Addr) -1l)
+
+/* 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)
+{
+ int check_notes (Elf_Data *data, GElf_Addr data_elfaddr)
+ {
+ 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;
+ }
+
+ 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,
+ ELF_T_NHDR),
+ phdr->p_vaddr);
+ }
+ }
+ 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);
+ }
+ }
+ 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/3rdparty/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c b/3rdparty/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c
new file mode 100644
index 0000000..6e22cf6
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdwelf/dwelfheaders.pri b/3rdparty/elfutils/libdwelf/dwelfheaders.pri
new file mode 100644
index 0000000..d214fae
--- /dev/null
+++ b/3rdparty/elfutils/libdwelf/dwelfheaders.pri
@@ -0,0 +1,5 @@
+HEADERS += \
+ $$PWD/libdwelf.h \
+ $$PWD/libdwelfP.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/libdwelf/libdwelf.h b/3rdparty/elfutils/libdwelf/libdwelf.h
new file mode 100644
index 0000000..e16dc0f
--- /dev/null
+++ b/3rdparty/elfutils/libdwelf/libdwelf.h
@@ -0,0 +1,72 @@
+/* Interfaces 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 <http://www.gnu.org/licenses/>. */
+
+#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 occured. */
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libdwelf.h */
diff --git a/3rdparty/elfutils/libdwelf/libdwelf.pro b/3rdparty/elfutils/libdwelf/libdwelf.pro
new file mode 100644
index 0000000..f3736a0
--- /dev/null
+++ b/3rdparty/elfutils/libdwelf/libdwelf.pro
@@ -0,0 +1,14 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../dwelf
+
+include(../elfutils.pri)
+include(dwelfheaders.pri)
+include(../libdw/dwheaders.pri)
+include(../libdwfl/dwflheaders.pri)
+include(../libebl/eblheaders.pri)
+
+SOURCES += \
+ $$PWD/dwelf_dwarf_gnu_debugaltlink.c \
+ $$PWD/dwelf_elf_gnu_build_id.c \
+ $$PWD/dwelf_elf_gnu_debuglink.c
diff --git a/3rdparty/elfutils/libdwelf/libdwelfP.h b/3rdparty/elfutils/libdwelf/libdwelfP.h
new file mode 100644
index 0000000..d83c759
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBDWELFP_H
+#define _LIBDWELFP_H 1
+
+#include <libdwelf.h>
+#include "../libdw/libdwP.h" /* We need its INTDECLs. */
+#include <assert.h>
+#include <string.h>
+
+/* 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/3rdparty/elfutils/libdwfl/argp-std.c b/3rdparty/elfutils/libdwfl/argp-std.c
new file mode 100644
index 0000000..42b7e78
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/argp-std.c
@@ -0,0 +1,364 @@
+/* Standard argp argument parsers for tools using libdwfl.
+ Copyright (C) 2005-2010, 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <argp.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <libintl.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+#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 error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ inline void failure (Dwfl *dwfl, int errnum, const char *msg)
+ {
+ 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);
+ }
+ inline error_t fail (Dwfl *dwfl, int errnum, const char *msg)
+ {
+ failure (dwfl, errnum, msg);
+ return errnum == -1 ? EIO : errnum;
+ }
+
+ 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->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);
+ 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);
+
+ /* 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);
+ 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"));
+ result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
+ if (result != 0)
+ /* Non-fatal to have no modules since we do have the kernel. */
+ failure (dwfl, 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"));
+ 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);
+ opt->dwfl = dwfl;
+ }
+
+ if (opt->core)
+ {
+ int fd = open64 (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);
+ }
+
+ /* Non-fatal to not be able to attach to core, ignore error. */
+ INTUSE(dwfl_core_file_attach) (dwfl, core);
+
+ /* From now we leak FD and CORE. */
+
+ 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);
+ }
+
+ /* 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);
+ assert (result == 0);
+
+ /* 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/3rdparty/elfutils/libdwfl/core-file.c b/3rdparty/elfutils/libdwfl/core-file.c
new file mode 100644
index 0000000..50031ae
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/core-file.c
@@ -0,0 +1,589 @@
+/* Core file handling.
+ Copyright (C) 2008-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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "../libelf/libelfP.h" /* For NOTE_ALIGN. */
+#undef _
+#include "libdwflP.h"
+#include <gelf.h>
+
+#include <sys/param.h>
+#include <unistd.h>
+#include <endian.h>
+#include <byteswap.h>
+#include "system.h"
+
+
+/* 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, loff_t offset, loff_t size, loff_t *next)
+{
+ if (parent == NULL)
+ return NULL;
+
+ /* On failure return, we update *NEXT to point back at OFFSET. */
+ inline Elf *fail (int error)
+ {
+ if (next != NULL)
+ *next = offset;
+ //__libelf_seterrno (error);
+ __libdwfl_seterrno (DWFL_E (LIBELF, error));
+ return NULL;
+ }
+
+ loff_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 >= (loff_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 ((loff_t) parent->maximum_size - offset < size))
+ return fail (ELF_E_INVALID_ARCHIVE);
+ }
+
+ if (unlikely ((loff_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 == (loff_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 ((loff_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
+
+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;
+
+ 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.
+ 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 (mod->build_id_len > 0)
+ /* 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;
+
+ 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;
+}
+
+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;
+
+ inline void update_end ()
+ {
+ end = (phdr.p_offset + phdr.p_filesz + align - 1) & -align;
+ end_vaddr = (phdr.p_vaddr + phdr.p_memsz + align - 1) & -align;
+ }
+
+ update_end ();
+
+ /* Use following contiguous segments to get towards SIZE. */
+ inline bool more (size_t size)
+ {
+ while (end <= start || end - start < size)
+ {
+ if (phdr.p_filesz < phdr.p_memsz)
+ /* This segment is truncated, so no following one helps us. */
+ return false;
+
+ if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL))
+ return false;
+
+ if (phdr.p_type == PT_LOAD)
+ {
+ if (phdr.p_offset > end
+ || phdr.p_vaddr > end_vaddr)
+ /* It's discontiguous! */
+ return false;
+
+ update_end ();
+ }
+ }
+ return true;
+ }
+
+ /* 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;
+ }
+
+ free (dwfl->executable_for_core);
+ if (executable == NULL)
+ dwfl->executable_for_core = NULL;
+ else
+ {
+ dwfl->executable_for_core = strdup (executable);
+ if (dwfl->executable_for_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, &notes_phdr);
+ if (unlikely (ndx <= 0))
+ 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,
+ 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 SHARED
+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/3rdparty/elfutils/libdwfl/cu.c b/3rdparty/elfutils/libdwfl/cu.c
new file mode 100644
index 0000000..5ce531b
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/cu.c
@@ -0,0 +1,312 @@
+/* Keeping track of DWARF compilation units in libdwfl.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+#include "../libdw/memory-access.h"
+#include <search.h>
+
+
+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;
+ mod->aranges = (realloc (aranges, naranges * sizeof aranges[0])
+ ?: 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)
+{
+ /* These are real CUs, so there never is a type_sig8. Note
+ initialization of dwkey.start and offset_size in intern_cu ()
+ to see why this calculates the same value for both key and
+ die.cu search items. */
+ return DIE_OFFSET_FROM_CU_OFFSET (cu->die.cu->start, cu->die.cu->offset_size,
+ 0);
+}
+
+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)
+{
+ struct Dwarf_CU dwkey;
+ struct dwfl_cu key;
+ key.die.cu = &dwkey;
+ dwkey.offset_size = 0;
+ dwkey.start = cuoff - (3 * 0 - 4 + 3);
+ 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)
+ {
+ if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size))
+ {
+ /* This is the EOF marker. Now we have interned all the CUs.
+ One increment in MOD->lazycu counts not having hit EOF yet. */
+ *found = (void *) -1l;
+ less_lazy (mod);
+ }
+ else
+ {
+ /* 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;
+
+ /* XXX use non-searching lookup */
+ Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cu->die);
+ if (die == NULL)
+ {
+ free (cu);
+ return DWFL_E_LIBDW;
+ }
+ assert (die == &cu->die);
+
+ 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)->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/3rdparty/elfutils/libdwfl/derelocate.c b/3rdparty/elfutils/libdwfl/derelocate.c
new file mode 100644
index 0000000..da67908
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/derelocate.c
@@ -0,0 +1,401 @@
+/* Recover relocatibility for addresses computed from debug information.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#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;
+
+ return 0;
+}
+
+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);
+ return -1;
+ }
+
+ 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 = alloca (sizeof *newref);
+ 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 (mod->reloc_info == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return -1;
+ }
+
+ struct secref **sortrefs = alloca (nrefs * sizeof sortrefs[0]);
+ 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;
+ }
+
+ 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;
+ }
+ }
+ }
+ }
+
+ 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 (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/3rdparty/elfutils/libdwfl/dwfl_addrdie.c b/3rdparty/elfutils/libdwfl/dwfl_addrdie.c
new file mode 100644
index 0000000..1e9b3ab
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_addrdie.c
@@ -0,0 +1,36 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_addrdwarf.c b/3rdparty/elfutils/libdwfl/dwfl_addrdwarf.c
new file mode 100644
index 0000000..ba412ec
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_addrdwarf.c
@@ -0,0 +1,37 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_addrmodule.c b/3rdparty/elfutils/libdwfl/dwfl_addrmodule.c
new file mode 100644
index 0000000..9234eb7
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_addrmodule.c
@@ -0,0 +1,38 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_begin.c b/3rdparty/elfutils/libdwfl/dwfl_begin.c
new file mode 100644
index 0000000..44c16a9
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_begin.c
@@ -0,0 +1,51 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c b/3rdparty/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c
new file mode 100644
index 0000000..f1c64bc
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c
@@ -0,0 +1,128 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <unistd.h>
+
+
+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/3rdparty/elfutils/libdwfl/dwfl_build_id_find_elf.c b/3rdparty/elfutils/libdwfl/dwfl_build_id_find_elf.c
new file mode 100644
index 0000000..062aad1
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_build_id_find_elf.c
@@ -0,0 +1,174 @@
+/* Find an ELF file for a module from its build ID.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <fcntl.h>
+#include <unistd.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)
+{
+ /* Search debuginfo_path directories' .build-id/ subdirectories. */
+
+ char id_name[sizeof "/.build-id/" + 1 + id_len * 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]);
+ assert (n == 3);
+ 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]);
+ assert (n == 2);
+ }
+ 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 = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+ ?: DEFAULT_DEBUGINFO_PATH);
+
+ int fd = -1;
+ char *dir;
+ while (fd < 0 && (dir = strsep (&path, ":")) != 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 (open64 (name, O_RDONLY));
+ if (fd >= 0)
+ {
+ if (*file_name != NULL)
+ free (*file_name);
+ *file_name = canonicalize_file_name (name);
+ if (*file_name == NULL)
+ {
+ *file_name = name;
+ name = NULL;
+ }
+ }
+ free (name);
+ }
+
+ /* 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->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). */
+ int fd = open64 (mod->dwfl->executable_for_core, O_RDONLY);
+ if (fd >= 0)
+ {
+ *file_name = strdup (mod->dwfl->executable_for_core);
+ 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 if (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/3rdparty/elfutils/libdwfl/dwfl_cumodule.c b/3rdparty/elfutils/libdwfl/dwfl_cumodule.c
new file mode 100644
index 0000000..c5cf004
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_cumodule.c
@@ -0,0 +1,36 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_cumodule (Dwarf_Die *cudie)
+{
+ struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+ return cu->mod;
+}
diff --git a/3rdparty/elfutils/libdwfl/dwfl_dwarf_line.c b/3rdparty/elfutils/libdwfl/dwfl_dwarf_line.c
new file mode 100644
index 0000000..e96f859
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_dwarf_line.c
@@ -0,0 +1,43 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_end.c b/3rdparty/elfutils/libdwfl/dwfl_end.c
new file mode 100644
index 0000000..33cae48
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_end.c
@@ -0,0 +1,54 @@
+/* Finish a session using libdwfl.
+ Copyright (C) 2005, 2008, 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+void
+dwfl_end (Dwfl *dwfl)
+{
+ if (dwfl == NULL)
+ return;
+
+ 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);
+ }
+
+ free (dwfl->executable_for_core);
+ free (dwfl);
+}
diff --git a/3rdparty/elfutils/libdwfl/dwfl_error.c b/3rdparty/elfutils/libdwfl/dwfl_error.c
new file mode 100644
index 0000000..d9ca9e7
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_error.c
@@ -0,0 +1,159 @@
+/* Error handling in libdwfl.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#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)
+
+
+static const struct msgtable
+{
+#define DWFL_ERROR(name, text) char msg_##name[sizeof text];
+ DWFL_ERRORS
+#undef DWFL_ERROR
+} msgtable =
+ {
+#define DWFL_ERROR(name, text) text,
+ DWFL_ERRORS
+#undef DWFL_ERROR
+ };
+#define msgstr (&msgtable.msg_NOERROR[0])
+
+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);
+}
+
+
+const char *
+dwfl_errmsg (error)
+ 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 strerror_r (error & 0xffff, "bad", 0);
+ 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/3rdparty/elfutils/libdwfl/dwfl_frame.c b/3rdparty/elfutils/libdwfl/dwfl_frame.c
new file mode 100644
index 0000000..f6f86c0
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_frame.c
@@ -0,0 +1,474 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <sys/ptrace.h>
+#include <unistd.h>
+
+/* 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];
+ 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
+state_free (Dwfl_Frame *state)
+{
+ Dwfl_Thread *thread = state->thread;
+ assert (thread->unwound == state);
+ thread->unwound = state->unwound;
+ free (state);
+}
+
+static void
+thread_free_all_states (Dwfl_Thread *thread)
+{
+ while (thread->unwound)
+ state_free (thread->unwound);
+}
+
+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;
+ if (thread_callbacks == NULL || 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 (strncmp (mod->name, "[vdso: ", 7) == 0
+ || 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)
+ {
+ Dwfl_Error saved_errno = dwfl_errno ();
+ thread_free_all_states (&thread);
+ __libdwfl_seterrno (saved_errno);
+ return -1;
+ }
+ if (thread.tid == 0)
+ {
+ thread_free_all_states (&thread);
+ __libdwfl_seterrno (DWFL_E_NOERROR);
+ return 0;
+ }
+ int err = callback (&thread, arg);
+ if (err != DWARF_CB_OK)
+ {
+ thread_free_all_states (&thread);
+ 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))
+ {
+ int err;
+ thread.tid = tid;
+ err = callback (&thread, arg);
+ thread_free_all_states (&thread);
+ return err;
+ }
+
+ 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)
+{
+ if (thread->unwound != NULL)
+ {
+ /* We had to be called from inside CALLBACK. */
+ __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
+ return -1;
+ }
+ 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))
+ {
+ thread_free_all_states (thread);
+ return -1;
+ }
+ if (! state_fetch_pc (thread->unwound))
+ {
+ if (process->callbacks->thread_detach)
+ process->callbacks->thread_detach (thread, thread->callbacks_arg);
+ thread_free_all_states (thread);
+ return -1;
+ }
+
+ Dwfl_Frame *state;
+ do
+ {
+ state = thread->unwound;
+ int err = callback (state, arg);
+ if (err != DWARF_CB_OK)
+ {
+ if (process->callbacks->thread_detach)
+ process->callbacks->thread_detach (thread, thread->callbacks_arg);
+ thread_free_all_states (thread);
+ return err;
+ }
+ __libdwfl_frame_unwind (state);
+ /* The old frame is no longer needed. */
+ state_free (thread->unwound);
+ state = thread->unwound;
+ }
+ 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)
+ {
+ thread_free_all_states (thread);
+ __libdwfl_seterrno (err);
+ return -1;
+ }
+ assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
+ thread_free_all_states (thread);
+ return 0;
+}
+INTDEF(dwfl_thread_getframes)
diff --git a/3rdparty/elfutils/libdwfl/dwfl_frame_pc.c b/3rdparty/elfutils/libdwfl/dwfl_frame_pc.c
new file mode 100644
index 0000000..296c815
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libdwfl/dwfl_frame_regs.c b/3rdparty/elfutils/libdwfl/dwfl_frame_regs.c
new file mode 100644
index 0000000..10803fe
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_frame_regs.c
@@ -0,0 +1,57 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_getdwarf.c b/3rdparty/elfutils/libdwfl/dwfl_getdwarf.c
new file mode 100644
index 0000000..8d1d9ba
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_getdwarf.c
@@ -0,0 +1,59 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_getmodules.c b/3rdparty/elfutils/libdwfl/dwfl_getmodules.c
new file mode 100644
index 0000000..eed9b4f
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_getmodules.c
@@ -0,0 +1,92 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_getsrc.c b/3rdparty/elfutils/libdwfl/dwfl_getsrc.c
new file mode 100644
index 0000000..8d4ae02
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_getsrc.c
@@ -0,0 +1,36 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_getsrclines.c b/3rdparty/elfutils/libdwfl/dwfl_getsrclines.c
new file mode 100644
index 0000000..bdfcf5c
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_getsrclines.c
@@ -0,0 +1,48 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_line_comp_dir.c b/3rdparty/elfutils/libdwfl/dwfl_line_comp_dir.c
new file mode 100644
index 0000000..bda09c4
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_line_comp_dir.c
@@ -0,0 +1,43 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <dwarf.h>
+
+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/3rdparty/elfutils/libdwfl/dwfl_linecu.c b/3rdparty/elfutils/libdwfl/dwfl_linecu.c
new file mode 100644
index 0000000..ce78d29
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_linecu.c
@@ -0,0 +1,41 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_lineinfo.c b/3rdparty/elfutils/libdwfl/dwfl_lineinfo.c
new file mode 100644
index 0000000..dfb27d8
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_lineinfo.c
@@ -0,0 +1,55 @@
+/* Get information from a source line record returned by libdwfl.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#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;
+
+ 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/3rdparty/elfutils/libdwfl/dwfl_linemodule.c b/3rdparty/elfutils/libdwfl/dwfl_linemodule.c
new file mode 100644
index 0000000..e4a35e0
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_linemodule.c
@@ -0,0 +1,38 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_linemodule (Dwfl_Line *line)
+{
+ if (line == NULL)
+ return NULL;
+
+ return dwfl_linecu (line)->mod;
+}
diff --git a/3rdparty/elfutils/libdwfl/dwfl_module.c b/3rdparty/elfutils/libdwfl/dwfl_module.c
new file mode 100644
index 0000000..8efcfaa
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module.c
@@ -0,0 +1,222 @@
+/* Maintenance of module list in libdwfl.
+ Copyright (C) 2005, 2006, 2007, 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <search.h>
+#include <unistd.h>
+
+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);
+ }
+
+ 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);
+
+ if (mod->eh_cfi != NULL)
+ dwarf_cfi_end (mod->eh_cfi);
+
+ free (mod->name);
+ 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)
+
+/* 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;
+
+ inline Dwfl_Module *use (Dwfl_Module *mod)
+ {
+ mod->next = *tailp;
+ *tailp = mod;
+
+ if (unlikely (dwfl->lookup_module != NULL))
+ {
+ free (dwfl->lookup_module);
+ dwfl->lookup_module = NULL;
+ }
+
+ return mod;
+ }
+
+ 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);
+ }
+
+ 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);
+}
+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/3rdparty/elfutils/libdwfl/dwfl_module_addrdie.c b/3rdparty/elfutils/libdwfl/dwfl_module_addrdie.c
new file mode 100644
index 0000000..20d2842
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_addrdie.c
@@ -0,0 +1,45 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_addrname.c b/3rdparty/elfutils/libdwfl/dwfl_module_addrname.c
new file mode 100644
index 0000000..88a8139
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_addrname.c
@@ -0,0 +1,38 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_addrsym.c b/3rdparty/elfutils/libdwfl/dwfl_module_addrsym.c
new file mode 100644
index 0000000..d205832
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_addrsym.c
@@ -0,0 +1,289 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+/* Returns the name of the symbol "closest" to ADDR.
+ Never returns symbols at addresses above ADDR. */
+
+const char *
+internal_function
+__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;
+
+ /* Return true iff we consider ADDR to lie in the same section as SYM. */
+ GElf_Word addr_shndx = SHN_UNDEF;
+ Elf *addr_symelf = NULL;
+ inline bool same_section (GElf_Addr value, Elf *symelf, GElf_Word shndx)
+ {
+ /* For absolute symbols and the like, only match exactly. */
+ if (shndx >= SHN_LORESERVE)
+ return value == 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 (! adjust_st_value)
+ {
+ Dwarf_Addr v;
+ if (addr_shndx == SHN_UNDEF)
+ {
+ v = addr;
+ addr_shndx = __libdwfl_find_section_ndx (mod, &v);
+ }
+
+ v = value;
+ return addr_shndx == __libdwfl_find_section_ndx (mod, &v);
+ }
+
+ /* Figure out what section ADDR lies in. */
+ if (addr_shndx == SHN_UNDEF || addr_symelf != symelf)
+ {
+ GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, symelf, addr);
+ Elf_Scn *scn = NULL;
+ addr_shndx = SHN_ABS;
+ 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)
+ {
+ addr_shndx = elf_ndxscn (scn);
+ break;
+ }
+ }
+ }
+
+ return shndx == addr_shndx && addr_symelf == 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 = NULL;
+ GElf_Addr closest_value = 0;
+ GElf_Word closest_shndx = SHN_UNDEF;
+ Elf *closest_elf = NULL;
+
+ /* Keep track of an eligible symbol with st_size == 0 as a fallback. */
+ const char *sizeless_name = NULL;
+ GElf_Sym sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF };
+ GElf_Addr sizeless_value = 0;
+ GElf_Word sizeless_shndx = SHN_UNDEF;
+ Elf *sizeless_elf = NULL;
+
+ /* Keep track of the lowest address a relevant sizeless symbol could have. */
+ GElf_Addr min_label = 0;
+
+ /* Try one symbol and associated value from the search table. */
+ inline void try_sym_value (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 > min_label)
+ min_label = value + sym->st_size;
+
+ if (sym->st_size == 0 || addr - value < sym->st_size)
+ {
+ /* Return GELF_ST_BIND as higher-is-better integer. */
+ 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;
+ }
+ }
+
+ /* This symbol is a better candidate than the current one
+ if it's closer to ADDR or is global when it was local. */
+ if (closest_name == NULL
+ || closest_value < value
+ || binding_value (closest_sym) < binding_value (sym))
+ {
+ if (sym->st_size != 0)
+ {
+ *closest_sym = *sym;
+ closest_value = value;
+ closest_shndx = shndx;
+ closest_elf = elf;
+ closest_name = name;
+ }
+ else if (closest_name == NULL
+ && value >= min_label
+ && same_section (value,
+ resolved ? 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. */
+ sizeless_sym = *sym;
+ sizeless_value = value;
+ sizeless_shndx = shndx;
+ sizeless_elf = elf;
+ 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
+ && closest_value == value
+ && ((closest_sym->st_size > sym->st_size
+ && (binding_value (closest_sym)
+ <= binding_value (sym)))
+ || (closest_sym->st_size >= sym->st_size
+ && (binding_value (closest_sym)
+ < binding_value (sym)))))
+ {
+ *closest_sym = *sym;
+ closest_value = value;
+ closest_shndx = shndx;
+ closest_elf = elf;
+ closest_name = name;
+ }
+ }
+ }
+
+ /* Look through the symbol table for a matching symbol. */
+ inline void search_table (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 (mod, i, &sym, &value,
+ &shndx, &elf, NULL,
+ &resolved, adjust_st_value);
+ if (name != NULL && name[0] != '\0'
+ && sym.st_shndx != SHN_UNDEF
+ && value <= 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 (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 && mod->e_type != ET_REL)
+ {
+ GElf_Addr adjusted_st_value;
+ adjusted_st_value = dwfl_adjusted_st_value (mod, elf,
+ sym.st_value);
+ if (value != adjusted_st_value && adjusted_st_value <= addr)
+ try_sym_value (adjusted_st_value, &sym, name, shndx,
+ elf, false);
+ }
+ }
+ }
+ }
+
+ /* 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) (mod);
+ if (first_global < 0)
+ return NULL;
+ search_table (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 (closest_name == NULL && first_global > 1
+ && (sizeless_name == NULL || sizeless_value != addr))
+ search_table (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 (closest_name == NULL
+ && sizeless_name != NULL && sizeless_value >= min_label)
+ {
+ *closest_sym = sizeless_sym;
+ closest_value = sizeless_value;
+ closest_shndx = sizeless_shndx;
+ closest_elf = sizeless_elf;
+ closest_name = sizeless_name;
+ }
+
+ *off = addr - closest_value;
+
+ if (shndxp != NULL)
+ *shndxp = closest_shndx;
+ if (elfp != NULL)
+ *elfp = closest_elf;
+ if (biasp != NULL)
+ *biasp = dwfl_adjusted_st_value (mod, closest_elf, 0);
+ return 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/3rdparty/elfutils/libdwfl/dwfl_module_build_id.c b/3rdparty/elfutils/libdwfl/dwfl_module_build_id.c
new file mode 100644
index 0000000..350bbf8
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_build_id.c
@@ -0,0 +1,117 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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 SHARED
+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/3rdparty/elfutils/libdwfl/dwfl_module_dwarf_cfi.c b/3rdparty/elfutils/libdwfl/dwfl_module_dwarf_cfi.c
new file mode 100644
index 0000000..5182d6a
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_dwarf_cfi.c
@@ -0,0 +1,71 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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 (mod, bias)
+ 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/3rdparty/elfutils/libdwfl/dwfl_module_eh_cfi.c b/3rdparty/elfutils/libdwfl/dwfl_module_eh_cfi.c
new file mode 100644
index 0000000..da10d9f
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_eh_cfi.c
@@ -0,0 +1,57 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include "../libdw/cfi.h"
+
+Dwarf_CFI *
+dwfl_module_eh_cfi (mod, bias)
+ 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/3rdparty/elfutils/libdwfl/dwfl_module_getdwarf.c b/3rdparty/elfutils/libdwfl/dwfl_module_getdwarf.c
new file mode 100644
index 0000000..494407d
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_getdwarf.c
@@ -0,0 +1,1358 @@
+/* Find debugging and symbol information for a module in libdwfl.
+ Copyright (C) 2005-2012, 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
+#include "../libelf/libelfP.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 (open64 (*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 explictly 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;
+}
+
+/* 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 (undodata->d_size != (src.d_size
+ + phnum * phentsize
+ + (shnum - 1) * shentsize)))
+ return DWFL_E_BAD_PRELINK;
+
+ /* 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;
+ {
+ union
+ {
+ Elf32_Phdr p32[phnum];
+ Elf64_Phdr p64[phnum];
+ } phdr;
+ dst.d_buf = &phdr;
+ dst.d_size = sizeof phdr;
+ if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
+ ehdr.e32.e_ident[EI_DATA]) == NULL))
+ return DWFL_E_LIBELF;
+ if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
+ {
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdr.p32[i].p_type == PT_INTERP)
+ {
+ undo_interp = phdr.p32[i].p_vaddr;
+ break;
+ }
+ }
+ else
+ {
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdr.p64[i].p_type == PT_INTERP)
+ {
+ undo_interp = phdr.p64[i].p_vaddr;
+ break;
+ }
+ }
+ }
+
+ 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 - 1, EV_CURRENT);
+
+ union
+ {
+ Elf32_Shdr s32[shnum - 1];
+ Elf64_Shdr s64[shnum - 1];
+ } shdr;
+ dst.d_buf = &shdr;
+ dst.d_size = sizeof shdr;
+ if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
+ ehdr.e32.e_ident[EI_DATA]) == NULL))
+ 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;
+
+ inline void consider_shdr (GElf_Addr interp,
+ GElf_Word sh_type,
+ GElf_Xword sh_flags,
+ GElf_Addr sh_addr,
+ GElf_Xword sh_size)
+ {
+ 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 > highest)
+ highest = sh_end;
+ }
+ }
+
+ 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))
+ return DWFL_E_LIBELF;
+ consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
+ sh->sh_addr, sh->sh_size);
+ }
+ if (highest > mod->main.vaddr)
+ {
+ mod->main.address_sync = highest;
+
+ highest = 0;
+ if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
+ for (size_t i = 0; i < shnum - 1; ++i)
+ consider_shdr (undo_interp, shdr.s32[i].sh_type, shdr.s32[i].sh_flags,
+ shdr.s32[i].sh_addr, shdr.s32[i].sh_size);
+ else
+ for (size_t i = 0; i < shnum - 1; ++i)
+ consider_shdr (undo_interp, shdr.s64[i].sh_type, shdr.s64[i].sh_flags,
+ shdr.s64[i].sh_addr, shdr.s64[i].sh_size);
+
+ if (highest > file->vaddr)
+ file->address_sync = highest;
+ else
+ return DWFL_E_BAD_PRELINK;
+ }
+
+ 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;
+ }
+ }
+}
+
+/* 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;
+
+ enum
+ {
+ i_symtab,
+ i_strtab,
+ i_hash,
+ i_gnu_hash,
+ i_max
+ };
+ 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;
+ }
+
+ /* Translate pointers into file offsets. ADJUST is either zero
+ in case the dynamic segment wasn't adjusted or mod->main_bias. */
+ void translate_offs (GElf_Addr adjust)
+ {
+ 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);
+ 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;
+
+ 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;
+ }
+ }
+ }
+
+ /* First try unadjusted, like ELF files from disk, vdso.
+ Then try for already adjusted dynamic section, like ELF
+ from remote memory. */
+ translate_offs (0);
+ if (mod->symfile == NULL)
+ translate_offs (mod->main_bias);
+
+ 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:
+ 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->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. */
+
+ mod->symstrdata = elf_getdata (elf_getscn (mod->symfile->elf, strshndx),
+ NULL);
+ if (mod->symstrdata == NULL || mod->symstrdata->d_buf == NULL)
+ goto elferr;
+
+ if (xndxscn == NULL)
+ mod->symxndxdata = NULL;
+ else
+ {
+ mod->symxndxdata = elf_getdata (xndxscn, NULL);
+ if (mod->symxndxdata == NULL || mod->symxndxdata->d_buf == NULL)
+ goto elferr;
+ }
+
+ mod->symdata = elf_getdata (symscn, NULL);
+ if (mod->symdata == NULL || mod->symdata->d_buf == NULL)
+ goto elferr;
+
+ // Sanity check number of symbols.
+ GElf_Shdr shdr_mem, *shdr = gelf_getshdr (symscn, &shdr_mem);
+ if (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;
+ }
+
+ mod->aux_symstrdata = elf_getdata (elf_getscn (mod->aux_sym.elf,
+ aux_strshndx),
+ NULL);
+ if (mod->aux_symstrdata == NULL || mod->aux_symstrdata->d_buf == NULL)
+ goto aux_cleanup;
+
+ if (aux_xndxscn == NULL)
+ mod->aux_symxndxdata = NULL;
+ else
+ {
+ mod->aux_symxndxdata = elf_getdata (aux_xndxscn, NULL);
+ if (mod->aux_symxndxdata == NULL
+ || mod->aux_symxndxdata->d_buf == NULL)
+ goto aux_cleanup;
+ }
+
+ 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;
+
+ /* 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;
+ }
+ }
+
+ 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);
+ }
+
+ /* 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/3rdparty/elfutils/libdwfl/dwfl_module_getelf.c b/3rdparty/elfutils/libdwfl/dwfl_module_getelf.c
new file mode 100644
index 0000000..f20fb04
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_getelf.c
@@ -0,0 +1,67 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_getsrc.c b/3rdparty/elfutils/libdwfl/dwfl_module_getsrc.c
new file mode 100644
index 0000000..f6d8839
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_getsrc.c
@@ -0,0 +1,81 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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,
+ except with an end_sequence which can only be strictly equal. */
+ Dwarf_Line *line = &lines->info[l];
+ if (line->addr == addr
+ || (! 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/3rdparty/elfutils/libdwfl/dwfl_module_getsrc_file.c b/3rdparty/elfutils/libdwfl/dwfl_module_getsrc_file.c
new file mode 100644
index 0000000..20aa8a5
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_getsrc_file.c
@@ -0,0 +1,167 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+
+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)
+ {
+ inline const char *INTUSE(dwarf_line_file) (const Dwarf_Line *line)
+ {
+ return line->files->info[line->file].name;
+ }
+ inline Dwarf_Line *dwfl_line (const Dwfl_Line *line)
+ {
+ return &dwfl_linecu (line)->die.cu->lines->info[line->idx];
+ }
+ inline const char *dwfl_line_file (const Dwfl_Line *line)
+ {
+ return INTUSE(dwarf_line_file) (dwfl_line (line));
+ }
+
+ /* 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))
+ {
+ __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
+ return -1;
+ }
+ else
+ {
+ const char *file = INTUSE(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])
+ == INTUSE(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/3rdparty/elfutils/libdwfl/dwfl_module_getsym.c b/3rdparty/elfutils/libdwfl/dwfl_module_getsym.c
new file mode 100644
index 0000000..42d2b67
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_getsym.c
@@ -0,0 +1,216 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_info.c b/3rdparty/elfutils/libdwfl/dwfl_module_info.c
new file mode 100644
index 0000000..df16be4
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_info.c
@@ -0,0 +1,61 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_nextcu.c b/3rdparty/elfutils/libdwfl/dwfl_module_nextcu.c
new file mode 100644
index 0000000..6f81f4c
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_nextcu.c
@@ -0,0 +1,44 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_register_names.c b/3rdparty/elfutils/libdwfl/dwfl_module_register_names.c
new file mode 100644
index 0000000..2da4b53
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_register_names.c
@@ -0,0 +1,79 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+
+int
+dwfl_module_register_names (mod, func, arg)
+ Dwfl_Module *mod;
+ int (*func) (void *, int regno, const char *setname,
+ const char *prefix, const char *regname,
+ int bits, int type);
+ 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/3rdparty/elfutils/libdwfl/dwfl_module_report_build_id.c b/3rdparty/elfutils/libdwfl/dwfl_module_report_build_id.c
new file mode 100644
index 0000000..b41512b
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_report_build_id.c
@@ -0,0 +1,80 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_module_return_value_location.c b/3rdparty/elfutils/libdwfl/dwfl_module_return_value_location.c
new file mode 100644
index 0000000..ad83cbf
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_module_return_value_location.c
@@ -0,0 +1,64 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+
+int
+dwfl_module_return_value_location (mod, functypedie, locops)
+ 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/3rdparty/elfutils/libdwfl/dwfl_nextcu.c b/3rdparty/elfutils/libdwfl/dwfl_nextcu.c
new file mode 100644
index 0000000..9ea8388
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_nextcu.c
@@ -0,0 +1,82 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_onesrcline.c b/3rdparty/elfutils/libdwfl/dwfl_onesrcline.c
new file mode 100644
index 0000000..4c20d65
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_onesrcline.c
@@ -0,0 +1,56 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_report_elf.c b/3rdparty/elfutils/libdwfl/dwfl_report_elf.c
new file mode 100644
index 0000000..3a4ae2e
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_report_elf.c
@@ -0,0 +1,338 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+
+/* 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 layed 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;
+
+ 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 = open64 (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 SHARED
+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/3rdparty/elfutils/libdwfl/dwfl_segment_report_module.c b/3rdparty/elfutils/libdwfl/dwfl_segment_report_module.c
new file mode 100644
index 0000000..898457f
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_segment_report_module.c
@@ -0,0 +1,922 @@
+/* Sniff out modules from ELF headers visible in memory segments.
+ Copyright (C) 2008-2012, 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "../libelf/libelfP.h" /* For NOTE_ALIGN. */
+#undef _
+#include "libdwflP.h"
+#include "common.h"
+
+#include <elf.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <sys/param.h>
+#include <alloca.h>
+#include <endian.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+
+/* 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
+
+
+/* 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,
+ const void *build_id, size_t build_id_len)
+{
+ 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, elf_build_id, build_id_len) != 0)
+ return true;
+ }
+ }
+ 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;
+
+ 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];
+
+ inline bool segment_read (int segndx,
+ void **buffer, size_t *buffer_available,
+ GElf_Addr addr, size_t minread)
+ {
+ return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
+ addr, minread, memory_callback_arg);
+ }
+
+ inline void release_buffer (void **buffer, size_t *buffer_available)
+ {
+ if (*buffer != NULL)
+ (void) segment_read (-1, buffer, buffer_available, 0, 0);
+ }
+
+ /* 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;
+
+ inline int finish (void)
+ {
+ release_buffer (&buffer, &buffer_available);
+ if (elf != NULL)
+ elf_end (elf);
+ if (fd != -1)
+ close (fd);
+ return ndx;
+ }
+
+ if (segment_read (ndx, &buffer, &buffer_available,
+ start, sizeof (Elf64_Ehdr))
+ || memcmp (buffer, ELFMAG, SELFMAG) != 0)
+ return finish ();
+
+ inline bool read_portion (void **data, size_t *data_size,
+ GElf_Addr vaddr, size_t filesz)
+ {
+ if (vaddr - start + filesz > buffer_available
+ /* 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 + buffer, '\0',
+ buffer_available - (vaddr - start)) == NULL))
+ {
+ *data = NULL;
+ *data_size = filesz;
+ return segment_read (addr_segndx (dwfl, segment, vaddr, false),
+ data, data_size, vaddr, filesz);
+ }
+
+ /* We already have this whole note segment from our initial read. */
+ *data = vaddr - start + buffer;
+ *data_size = 0;
+ return false;
+ }
+
+ inline void finish_portion (void **data, size_t *data_size)
+ {
+ if (*data_size != 0)
+ release_buffer (data, data_size);
+ }
+
+ /* 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)
+ return finish ();
+ 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))
+ return finish ();
+ 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)
+ return finish ();
+ 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))
+ return finish ();
+ shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
+ break;
+
+ default:
+ return finish ();
+ }
+
+ /* 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)
+ return finish ();
+
+ 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 (&ph_buffer, &ph_buffer_size,
+ start + phoff, xlatefrom.d_size))
+ return finish ();
+
+ xlatefrom.d_buf = ph_buffer;
+
+ union
+ {
+ Elf32_Phdr p32[phnum];
+ Elf64_Phdr p64[phnum];
+ } phdrs;
+
+ xlateto.d_buf = &phdrs;
+ xlateto.d_size = sizeof phdrs;
+
+ /* 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. */
+ void *build_id = NULL;
+ size_t build_id_len = 0;
+ GElf_Addr build_id_vaddr = 0;
+
+ /* Consider a PT_NOTE we've found in the image. */
+ inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz)
+ {
+ /* If we have already seen a build ID, we don't care any more. */
+ if (build_id != NULL || filesz == 0)
+ return;
+
+ void *data;
+ size_t data_size;
+ if (read_portion (&data, &data_size, vaddr, filesz))
+ return;
+
+ assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+ void *notes;
+ if (ei_data == MY_ELFDATA)
+ notes = data;
+ else
+ {
+ notes = malloc (filesz);
+ if (unlikely (notes == NULL))
+ return;
+ xlatefrom.d_type = xlateto.d_type = 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,
+ ehdr.e32.e_ident[EI_DATA]) == NULL)
+ goto done;
+ }
+
+ const GElf_Nhdr *nh = notes;
+ while ((const void *) nh < (const void *) notes + filesz)
+ {
+ const void *note_name = nh + 1;
+ const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz);
+ if (unlikely ((size_t) ((const void *) notes + filesz
+ - note_desc) < 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 + vaddr;
+ build_id_len = nh->n_descsz;
+ build_id = malloc (nh->n_descsz);
+ if (likely (build_id != NULL))
+ memcpy (build_id, note_desc, build_id_len);
+ break;
+ }
+
+ nh = note_desc + NOTE_ALIGN (nh->n_descsz);
+ }
+
+ done:
+ if (notes != data)
+ free (notes);
+ finish_portion (&data, &data_size);
+ }
+
+ /* Consider each of the program headers we've read from the image. */
+ inline void consider_phdr (GElf_Word type,
+ GElf_Addr vaddr, GElf_Xword memsz,
+ GElf_Off offset, GElf_Xword filesz,
+ GElf_Xword align)
+ {
+ switch (type)
+ {
+ case PT_DYNAMIC:
+ dyn_vaddr = vaddr;
+ dyn_filesz = filesz;
+ break;
+
+ case PT_NOTE:
+ /* We calculate from the p_offset of the note segment,
+ because we don't yet know the bias for its p_vaddr. */
+ consider_notes (start + offset, filesz);
+ break;
+
+ case 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;
+ break;
+ }
+ }
+ if (ei_class == ELFCLASS32)
+ {
+ if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
+ found_bias = false; /* Trigger error check. */
+ else
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ consider_phdr (phdrs.p32[i].p_type,
+ phdrs.p32[i].p_vaddr, phdrs.p32[i].p_memsz,
+ phdrs.p32[i].p_offset, phdrs.p32[i].p_filesz,
+ phdrs.p32[i].p_align);
+ }
+ else
+ {
+ if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
+ found_bias = false; /* Trigger error check. */
+ else
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ consider_phdr (phdrs.p64[i].p_type,
+ phdrs.p64[i].p_vaddr, phdrs.p64[i].p_memsz,
+ phdrs.p64[i].p_offset, phdrs.p64[i].p_filesz,
+ phdrs.p64[i].p_align);
+ }
+
+ finish_portion (&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);
+ return finish ();
+ }
+
+ /* 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, build_id_len))
+ {
+ 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);
+ return finish ();
+ }
+ }
+
+ 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 = open64 (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, build_id_len);
+ }
+ if (invalid)
+ {
+ free (build_id);
+ return finish ();
+ }
+ }
+
+ /* 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;
+ inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
+ {
+ switch (tag)
+ {
+ default:
+ return false;
+
+ case DT_DEBUG:
+ execlike = true;
+ break;
+
+ case DT_SONAME:
+ soname_stroff = val;
+ break;
+
+ case DT_STRTAB:
+ dynstr_vaddr = val;
+ break;
+
+ case DT_STRSZ:
+ dynstrsz = val;
+ break;
+ }
+
+ return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
+ }
+
+ 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 (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
+ {
+ union
+ {
+ Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
+ Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
+ } dyn;
+
+ xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
+ xlatefrom.d_buf = (void *) dyn_data;
+ xlatefrom.d_size = dyn_filesz;
+ xlateto.d_buf = &dyn;
+ xlateto.d_size = sizeof dyn;
+
+ if (ei_class == ELFCLASS32)
+ {
+ if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
+ for (size_t i = 0; i < dyn_filesz / sizeof dyn.d32[0]; ++i)
+ if (consider_dyn (dyn.d32[i].d_tag, dyn.d32[i].d_un.d_val))
+ break;
+ }
+ else
+ {
+ if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
+ for (size_t i = 0; i < dyn_filesz / sizeof dyn.d64[0]; ++i)
+ if (consider_dyn (dyn.d64[i].d_tag, dyn.d64[i].d_un.d_val))
+ break;
+ }
+ }
+ finish_portion (&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 (&soname, &soname_size,
+ 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 != NULL
+ && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
+ build_id,
+ 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);
+ finish_portion (&soname, &soname_size);
+
+ if (unlikely (mod == NULL))
+ {
+ ndx = -1;
+ return finish ();
+ }
+
+ /* 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))
+ return finish ();
+
+ inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
+ {
+ void *into = contents + offset;
+ size_t read_size = size;
+ (void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
+ &into, &read_size, vaddr, size);
+ }
+
+ 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. */
+
+ inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
+ GElf_Off offset, GElf_Xword filesz)
+ {
+ if (type == PT_LOAD)
+ final_read (offset, vaddr + bias, filesz);
+ }
+
+ if (ei_class == ELFCLASS32)
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ read_phdr (phdrs.p32[i].p_type, phdrs.p32[i].p_vaddr,
+ phdrs.p32[i].p_offset, phdrs.p32[i].p_filesz);
+ else
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ read_phdr (phdrs.p64[i].p_type, phdrs.p64[i].p_vaddr,
+ phdrs.p64[i].p_offset, phdrs.p64[i].p_filesz);
+ }
+ 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)
+ final_read (have, start + have, file_trimmed_end - have);
+ }
+
+ 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;
+ elf = NULL;
+ fd = -1;
+ mod->main.vaddr = module_start - bias;
+ mod->main.address_sync = module_address_sync;
+ mod->main_bias = bias;
+ }
+
+ return finish ();
+}
diff --git a/3rdparty/elfutils/libdwfl/dwfl_validate_address.c b/3rdparty/elfutils/libdwfl/dwfl_validate_address.c
new file mode 100644
index 0000000..7334c3e
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_validate_address.c
@@ -0,0 +1,61 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/dwfl_version.c b/3rdparty/elfutils/libdwfl/dwfl_version.c
new file mode 100644
index 0000000..9673a53
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwfl_version.c
@@ -0,0 +1,36 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+
+const char *
+dwfl_version (dwfl)
+ Dwfl *dwfl __attribute__ ((unused));
+{
+ return PACKAGE_VERSION;
+}
diff --git a/3rdparty/elfutils/libdwfl/dwflheaders.pri b/3rdparty/elfutils/libdwfl/dwflheaders.pri
new file mode 100644
index 0000000..7acb427
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/dwflheaders.pri
@@ -0,0 +1,5 @@
+HEADERS += \
+ $$PWD/libdwfl.h \
+ $$PWD/libdwflP.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/libdwfl/elf-from-memory.c b/3rdparty/elfutils/libdwfl/elf-from-memory.c
new file mode 100644
index 0000000..b35fac7
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/elf-from-memory.c
@@ -0,0 +1,370 @@
+/* Reconstruct an ELF file by reading the segments out of remote memory.
+ Copyright (C) 2005-2011, 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "../libelf/libelfP.h"
+#undef _
+
+#include "libdwflP.h"
+
+#include <gelf.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* 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)
+{
+ /* First read in the file header and check its sanity. */
+
+ const size_t initial_bufsize = 256;
+ unsigned char *buffer = malloc (initial_bufsize);
+ if (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);
+ __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
+ return NULL;
+ }
+
+ if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
+ {
+ bad_elf:
+ free (buffer);
+ __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;
+ 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;
+ 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 < phnum * phentsize)
+ {
+ unsigned char *newbuf = realloc (buffer, phnum * phentsize);
+ if (newbuf == NULL)
+ {
+ free (buffer);
+ 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;
+ }
+
+ union
+ {
+ Elf32_Phdr p32[phnum];
+ Elf64_Phdr p64[phnum];
+ } phdrs;
+
+ xlateto.d_buf = &phdrs;
+ xlateto.d_size = sizeof phdrs;
+
+ /* 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;
+ switch (ehdr.e32.e_ident[EI_CLASS])
+ {
+ /* Sanity checks segments and calculates segment_end,
+ segments_end, segments_end_mem and loadbase (if not
+ found_base yet). Returns true if sanity checking failed,
+ false otherwise. */
+ inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
+ GElf_Xword filesz, GElf_Xword memsz)
+ {
+ /* Sanity check the segment load aligns with the pagesize. */
+ if (((vaddr - offset) & (pagesize - 1)) != 0)
+ return true;
+
+ 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;
+ return false;
+ }
+
+ case ELFCLASS32:
+ if (elf32_xlatetom (&xlateto, &xlatefrom,
+ ehdr.e32.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p32[i].p_type == PT_LOAD)
+ if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
+ phdrs.p32[i].p_filesz, phdrs.p32[i].p_memsz))
+ goto bad_elf;
+ break;
+
+ case ELFCLASS64:
+ if (elf64_xlatetom (&xlateto, &xlatefrom,
+ ehdr.e64.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p64[i].p_type == PT_LOAD)
+ if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
+ phdrs.p64[i].p_filesz, phdrs.p64[i].p_memsz))
+ goto bad_elf;
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ /* 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)
+ goto no_memory;
+
+ switch (ehdr.e32.e_ident[EI_CLASS])
+ {
+ /* Reads the given segment. Returns true if reading fails,
+ false otherwise. */
+ inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
+ GElf_Xword 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);
+ return nread <= 0;
+ }
+
+ case ELFCLASS32:
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p32[i].p_type == PT_LOAD)
+ if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
+ phdrs.p32[i].p_filesz))
+ 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)
+ {
+ ehdr.e32.e_shoff = 0;
+ ehdr.e32.e_shnum = 0;
+ ehdr.e32.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;
+ xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
+ xlatefrom.d_buf = &ehdr.e32;
+ xlateto.d_buf = buffer;
+ if (elf32_xlatetof (&xlateto, &xlatefrom,
+ ehdr.e32.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ break;
+
+ case ELFCLASS64:
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdrs.p64[i].p_type == PT_LOAD)
+ if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
+ phdrs.p64[i].p_filesz))
+ 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)
+ {
+ 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;
+ xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
+ xlatefrom.d_buf = &ehdr.e64;
+ xlateto.d_buf = buffer;
+ if (elf64_xlatetof (&xlateto, &xlatefrom,
+ ehdr.e64.e_ident[EI_DATA]) == NULL)
+ goto libelf_error;
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ /* 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/3rdparty/elfutils/libdwfl/find-debuginfo.c b/3rdparty/elfutils/libdwfl/find-debuginfo.c
new file mode 100644
index 0000000..3f5314a
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/find-debuginfo.c
@@ -0,0 +1,351 @@
+/* Standard find_debuginfo callback for libdwfl.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "system.h"
+
+
+/* Try to open64 [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 stat64 *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 (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 stat64 st;
+ int fd = TEMP_FAILURE_RETRY (open64 (fname, O_RDONLY));
+ if (fd < 0)
+ free (fname);
+ else if (fstat64 (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. */
+ 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);
+ if (debuglink_file == 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);
+ char *localname = alloca (len + sizeof ".debug");
+ 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 *path = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+ ?: DEFAULT_DEBUGINFO_PATH);
+
+ /* A leading - or + in the whole path sets whether to check file CRCs. */
+ bool defcheck = true;
+ if (path[0] == '-' || path[0] == '+')
+ {
+ defcheck = path[0] == '+';
+ ++path;
+ }
+
+ /* XXX dev/ino should be cached in struct dwfl_file. */
+ struct stat64 main_stat;
+ if (unlikely ((mod->main.fd != -1 ? fstat64 (mod->main.fd, &main_stat)
+ : file_name != NULL ? stat64 (file_name, &main_stat)
+ : -1) < 0))
+ {
+ main_stat.st_dev = 0;
+ main_stat.st_ino = 0;
+ }
+
+ char *file_dirname = (file_basename == file_name ? NULL
+ : strndupa (file_name, file_basename - 1 - file_name));
+ 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;
+
+ 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;
+ 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 + 1;
+ file = debuglink_file;
+ }
+ else
+ {
+ subdir = NULL;
+ file = basename (debuglink_file);
+ }
+ 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;
+ break;
+ }
+
+ char *fname = NULL;
+ int fd = try_open (&main_stat, dir, subdir, file, &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)
+ return -1;
+ else
+ continue;
+ }
+ break;
+ }
+ continue;
+ default:
+ return -1;
+ }
+ if (validate (mod, fd, check, debuglink_crc))
+ {
+ *debuginfo_file_name = fname;
+ return fd;
+ }
+ free (fname);
+ close (fd);
+ }
+
+ /* No dice. */
+ errno = 0;
+ 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)
+{
+ /* 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;
+ GElf_Addr vaddr;
+ if (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)
+ {
+ /* If FILE_NAME is a symlink, the debug file might be associated
+ with the symlink target name instead. */
+
+ char *canon = canonicalize_file_name (file_name);
+ if (canon != NULL && strcmp (file_name, canon))
+ fd = find_debuginfo_in_path (mod, canon,
+ debuglink_file, debuglink_crc,
+ debuginfo_file_name);
+ free (canon);
+ }
+
+ return fd;
+}
+INTDEF (dwfl_standard_find_debuginfo)
diff --git a/3rdparty/elfutils/libdwfl/frame_unwind.c b/3rdparty/elfutils/libdwfl/frame_unwind.c
new file mode 100644
index 0000000..16cebd0
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/frame_unwind.c
@@ -0,0 +1,725 @@
+/* Get previous frame state for an existing frame state.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <stdlib.h>
+#include "libdwflP.h"
+#include "../libdw/dwarf.h"
+#include <sys/ptrace.h>
+
+/* 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
+
+#ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+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, &regno))
+ 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, &regno))
+ 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);
+}
+
+/* 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;
+ }
+ Dwarf_Addr *stack = NULL;
+ size_t stack_used = 0, stack_allocated = 0;
+
+ bool
+ push (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 *stack_new = realloc (stack, stack_allocated * sizeof (*stack));
+ if (stack_new == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return false;
+ }
+ stack = stack_new;
+ }
+ stack[stack_used++] = val;
+ return true;
+ }
+
+ bool
+ pop (Dwarf_Addr *val)
+ {
+ if (stack_used == 0)
+ {
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ *val = stack[--stack_used];
+ return true;
+ }
+
+ 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);
+ return false;
+ }
+ break;
+ case DW_OP_addr:
+ if (! push (op->number + bias))
+ {
+ free (stack);
+ 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);
+ 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);
+ return false;
+ }
+ break;
+ case DW_OP_regx:
+ if (! state_get_reg (state, op->number, &val1) || ! push (val1))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_breg0 ... DW_OP_breg31:
+ if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
+ {
+ free (stack);
+ return false;
+ }
+ val1 += op->number;
+ if (! push (val1))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_bregx:
+ if (! state_get_reg (state, op->number, &val1))
+ {
+ free (stack);
+ return false;
+ }
+ val1 += op->number2;
+ if (! push (val1))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_dup:
+ if (! pop (&val1) || ! push (val1) || ! push (val1))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_drop:
+ if (! pop (&val1))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_pick:
+ if (stack_used <= op->number)
+ {
+ free (stack);
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ if (! push (stack[stack_used - 1 - op->number]))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_over:
+ if (! pop (&val1) || ! pop (&val2)
+ || ! push (val2) || ! push (val1) || ! push (val2))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ case DW_OP_swap:
+ if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
+ {
+ free (stack);
+ 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);
+ return false;
+ }
+ }
+ break;
+ case DW_OP_deref:
+ case DW_OP_deref_size:
+ if (process->callbacks->memory_read == NULL)
+ {
+ free (stack);
+ __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
+ return false;
+ }
+ if (! pop (&val1)
+ || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
+ process->callbacks_arg))
+ {
+ free (stack);
+ 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);
+ __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 &= (1 << (op->number * 8)) - 1;
+#endif
+ }
+ if (! push (val1))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+#define UNOP(atom, expr) \
+ case atom: \
+ if (! pop (&val1) || ! push (expr)) \
+ { \
+ free (stack); \
+ return false; \
+ } \
+ break;
+ UNOP (DW_OP_abs, abs ((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);
+ return false;
+ }
+ break;
+#define BINOP(atom, op) \
+ case atom: \
+ if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \
+ { \
+ free (stack); \
+ 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); \
+ return false; \
+ } \
+ break;
+ BINOP (DW_OP_and, &)
+ case DW_OP_div:
+ if (! pop (&val2) || ! pop (&val1))
+ {
+ free (stack);
+ return false;
+ }
+ if (val2 == 0)
+ {
+ free (stack);
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ if (! push ((int64_t) val1 / (int64_t) val2))
+ {
+ free (stack);
+ return false;
+ }
+ break;
+ BINOP (DW_OP_minus, -)
+ case DW_OP_mod:
+ if (! pop (&val2) || ! pop (&val1))
+ {
+ free (stack);
+ return false;
+ }
+ if (val2 == 0)
+ {
+ free (stack);
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ if (! push (val1 % val2))
+ {
+ free (stack);
+ 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);
+ return false;
+ }
+ if (val1 == 0)
+ break;
+ /* FALLTHRU */
+ 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);
+ /* 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);
+ 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);
+ return false;
+ }
+ free (stack);
+ 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;
+}
+
+static void
+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);
+ 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));
+}
+
+/* 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;
+ }
+ new_unwound (state);
+ Dwfl_Frame *unwound = state->unwound;
+ 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;
+ ebl_dwarf_to_regno (ebl, &ra);
+
+ 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, &reg_ops,
+ &reg_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, &regval))
+ continue;
+ }
+ else
+ {
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ continue;
+ }
+ }
+ else if (! expr_eval (state, frame, reg_ops, reg_nops, &regval, 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
+ && __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;
+ }
+ 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);
+ assert (ok);
+ /* 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;
+ new_unwound (state);
+ 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/3rdparty/elfutils/libdwfl/gzip.c b/3rdparty/elfutils/libdwfl/gzip.c
new file mode 100644
index 0000000..b7dde5d
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/gzip.c
@@ -0,0 +1,295 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include "system.h"
+
+#include <unistd.h>
+
+#ifdef LZMA
+# define USE_INFLATE 1
+# include <lzma.h>
+# 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 BZLIB
+# define USE_INFLATE 1
+# include <bzlib.h>
+# 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 <zlib.h>
+# define unzip __libdw_gunzip
+# define MAGIC "\037\213"
+# define Z(what) Z_##what
+#endif
+
+#define READ_SIZE (1 << 20)
+
+/* 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, off64_t start_offset,
+ void *mapped, size_t mapped_size,
+ void **whole, size_t *whole_size)
+{
+ void *buffer = NULL;
+ size_t size = 0;
+ inline bool bigger_buffer (size_t start)
+ {
+ size_t more = size ? size * 2 : start;
+ char *b = realloc (buffer, more);
+ while (unlikely (b == NULL) && more >= size + 1024)
+ b = realloc (buffer, more -= 1024);
+ if (unlikely (b == NULL))
+ return false;
+ buffer = b;
+ size = more;
+ return true;
+ }
+ inline void smaller_buffer (size_t end)
+ {
+ buffer = realloc (buffer, end) ?: end == 0 ? NULL : buffer;
+ size = end;
+ }
+
+ void *input_buffer = NULL;
+ off_t input_pos = 0;
+
+ inline Dwfl_Error fail (Dwfl_Error failure)
+ {
+ if (input_pos == (off_t) mapped_size)
+ *whole = input_buffer;
+ else
+ {
+ free (input_buffer);
+ *whole = NULL;
+ }
+ free (buffer);
+ return failure;
+ }
+
+ inline Dwfl_Error zlib_fail (int result)
+ {
+ switch (result)
+ {
+ case Z (MEM_ERROR):
+ return fail (DWFL_E_NOMEM);
+ case Z (ERRNO):
+ return fail (DWFL_E_ERRNO);
+ default:
+ return fail (DWFL_E_ZLIB);
+ }
+ }
+
+ if (mapped == NULL)
+ {
+ if (*whole == NULL)
+ {
+ input_buffer = malloc (READ_SIZE);
+ if (unlikely (input_buffer == NULL))
+ return DWFL_E_NOMEM;
+
+ ssize_t n = pread_retry (fd, input_buffer, READ_SIZE, start_offset);
+ if (unlikely (n < 0))
+ return zlib_fail (Z (ERRNO));
+
+ input_pos = n;
+ mapped = input_buffer;
+ mapped_size = n;
+ }
+ else
+ {
+ input_buffer = *whole;
+ input_pos = mapped_size = *whole_size;
+ }
+ }
+
+#define NOMAGIC(magic) \
+ (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;
+
+#if 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 = mapped_size };
+ int result = inflateInit (&z);
+ if (result != Z (OK))
+ {
+ inflateEnd (&z);
+ return zlib_fail (result);
+ }
+
+ do
+ {
+ if (z.avail_in == 0 && input_buffer != NULL)
+ {
+ ssize_t n = pread_retry (fd, input_buffer, READ_SIZE,
+ start_offset + input_pos);
+ if (unlikely (n < 0))
+ {
+ inflateEnd (&z);
+ return zlib_fail (Z (ERRNO));
+ }
+ z.next_in = input_buffer;
+ z.avail_in = n;
+ input_pos += n;
+ }
+ if (z.avail_out == 0)
+ {
+ ptrdiff_t pos = (void *) z.next_out - buffer;
+ if (!bigger_buffer (z.avail_in))
+ {
+ result = Z (MEM_ERROR);
+ break;
+ }
+ z.next_out = buffer + pos;
+ z.avail_out = 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 (total_out);
+#else
+ smaller_buffer (z.total_out);
+#endif
+
+ inflateEnd (&z);
+
+ if (result != Z (STREAM_END))
+ return zlib_fail (result);
+
+#else /* gzip only. */
+
+ /* Let the decompression library read the file directly. */
+
+ gzFile zf;
+ Dwfl_Error open_stream (void)
+ {
+ int d = dup (fd);
+ if (unlikely (d < 0))
+ return DWFL_E_BADELF;
+ if (start_offset != 0)
+ {
+ off64_t off = lseek (d, start_offset, SEEK_SET);
+ if (off != start_offset)
+ {
+ close (d);
+ return DWFL_E_BADELF;
+ }
+ }
+ zf = gzdopen (d, "r");
+ if (unlikely (zf == NULL))
+ {
+ close (d);
+ return zlib_fail (Z (MEM_ERROR));
+ }
+
+ /* From here on, zlib will close D. */
+
+ return DWFL_E_NOERROR;
+ }
+
+ Dwfl_Error result = open_stream ();
+
+ if (result == DWFL_E_NOERROR && gzdirect (zf))
+ {
+ gzclose (zf);
+ return fail (DWFL_E_BADELF);
+ }
+
+ if (result != DWFL_E_NOERROR)
+ return fail (result);
+
+ ptrdiff_t pos = 0;
+ while (1)
+ {
+ if (!bigger_buffer (1024))
+ {
+ gzclose (zf);
+ return zlib_fail (Z (MEM_ERROR));
+ }
+ int n = gzread (zf, buffer + pos, size - pos);
+ if (n < 0)
+ {
+ int code;
+ gzerror (zf, &code);
+ gzclose (zf);
+ return zlib_fail (code);
+ }
+ if (n == 0)
+ break;
+ pos += n;
+ }
+
+ gzclose (zf);
+ smaller_buffer (pos);
+#endif
+
+ free (input_buffer);
+
+ *whole = buffer;
+ *whole_size = size;
+
+ return DWFL_E_NOERROR;
+}
diff --git a/3rdparty/elfutils/libdwfl/image-header.c b/3rdparty/elfutils/libdwfl/image-header.c
new file mode 100644
index 0000000..a4f6799
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/image-header.c
@@ -0,0 +1,101 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include "system.h"
+
+#include <unistd.h>
+#include <endian.h>
+
+#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, off64_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/3rdparty/elfutils/libdwfl/libdwfl.h b/3rdparty/elfutils/libdwfl/libdwfl.h
new file mode 100644
index 0000000..2bb4f45
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/libdwfl.h
@@ -0,0 +1,812 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBDWFL_H
+#define _LIBDWFL_H 1
+
+#include "libdw.h"
+#include <stdio.h>
+
+/* 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 partical 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).
+
+ 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.
+
+ When NDX is the value succeeding the last call's NDX (or is implicitly
+ so as above), IDENT is nonnull and matches the value in the last call,
+ and the PHDR and BIAS values reflect a segment that would be contiguous,
+ in both memory and file, with the last segment reported, then this
+ segment may be coalesced internally with preceding segments. When given
+ an address inside this segment, dwfl_addrsegment may return the NDX of a
+ preceding contiguous segment. To prevent coalesced segments, always
+ pass a null pointer for IDENT.
+
+ The values passed are not stored (except to track coalescence).
+ The only information that can be extracted from DWFL later is the
+ mapping of an address to a segment index that starts at or below
+ it. 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
+ 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 /bin/ls, the default string
+ ":.debug:/usr/lib/debug" says to look in /bin, then /bin/.debug,
+ then /usr/lib/debug/bin, 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) __attribute__ ((const));
+
+
+/*** 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__ (1, 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 wil 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 fo 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 <FIRSTREG..FIRSTREG+NREGS)
+ (inclusive..exclusive) set their content to REGS (array of NREGS items).
+ Function returns false if any of the registers has invalid number. */
+bool dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg,
+ unsigned nregs, const Dwarf_Word *regs)
+ __nonnull_attribute__ (1, 4);
+
+/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation.
+ If PC is not contained among DWARF registers passed by
+ dwfl_thread_state_registers on the target architecture pass the PC value
+ here. */
+void dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
+ __nonnull_attribute__ (1);
+
+/* Iterate through the threads for a process. Returns zero if all threads have
+ been processed by the callback, returns -1 on error, or the value of the
+ callback when not DWARF_CB_OK. -1 returned on error will set dwfl_errno ().
+ Keeps calling the callback with the next thread while the callback returns
+ DWARF_CB_OK, till there are no more threads. */
+int dwfl_getthreads (Dwfl *dwfl,
+ int (*callback) (Dwfl_Thread *thread, void *arg),
+ void *arg)
+ __nonnull_attribute__ (1, 2);
+
+/* Iterate through the frames for a thread. Returns zero if all frames
+ have been processed by the callback, returns -1 on error, or the value of
+ the callback when not DWARF_CB_OK. -1 returned on error will
+ set dwfl_errno (). Some systems return error instead of zero on end of the
+ backtrace, for cross-platform compatibility callers should consider error as
+ a zero. Keeps calling the callback with the next frame while the callback
+ returns DWARF_CB_OK, till there are no more frames. On start will call the
+ set_initial_registers callback and on return will call the detach_thread
+ callback of the Dwfl_Thread. */
+int dwfl_thread_getframes (Dwfl_Thread *thread,
+ int (*callback) (Dwfl_Frame *state, void *arg),
+ void *arg)
+ __nonnull_attribute__ (1, 2);
+
+/* Like dwfl_thread_getframes, but specifying the thread by its unique
+ identifier number. Returns zero if all frames have been processed
+ by the callback, returns -1 on error (and when no thread with
+ the given thread id number exists), or the value of the callback
+ when not DWARF_CB_OK. -1 returned on error will set dwfl_errno (). */
+int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
+ int (*callback) (Dwfl_Frame *thread, void *arg),
+ void *arg)
+ __nonnull_attribute__ (1, 3);
+
+/* Return *PC (program counter) for thread-specific frame STATE.
+ Set *ISACTIVATION according to DWARF frame "activation" definition.
+ Typically you need to substract 1 from *PC if *ACTIVATION is false to safely
+ find function of the caller. ACTIVATION may be NULL. PC must not be NULL.
+ Function returns false if it failed to find *PC. */
+bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation)
+ __nonnull_attribute__ (1, 2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libdwfl.h */
diff --git a/3rdparty/elfutils/libdwfl/libdwfl.pro b/3rdparty/elfutils/libdwfl/libdwfl.pro
new file mode 100644
index 0000000..d3af0eb
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/libdwfl.pro
@@ -0,0 +1,76 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../dwfl
+
+include(../elfutils.pri)
+include(dwflheaders.pri)
+include(../libdw/dwheaders.pri)
+include(../libebl/eblheaders.pri)
+include(../libdwelf/dwelfheaders.pri)
+
+SOURCES += \
+ $$PWD/argp-std.c \
+ $$PWD/core-file.c \
+ $$PWD/cu.c \
+ $$PWD/derelocate.c \
+ $$PWD/dwfl_addrdie.c \
+ $$PWD/dwfl_addrdwarf.c \
+ $$PWD/dwfl_addrmodule.c \
+ $$PWD/dwfl_begin.c \
+ $$PWD/dwfl_build_id_find_debuginfo.c \
+ $$PWD/dwfl_build_id_find_elf.c \
+ $$PWD/dwfl_cumodule.c \
+ $$PWD/dwfl_dwarf_line.c \
+ $$PWD/dwfl_end.c \
+ $$PWD/dwfl_error.c \
+ $$PWD/dwfl_frame_pc.c \
+ $$PWD/dwfl_frame_regs.c \
+ $$PWD/dwfl_frame.c \
+ $$PWD/dwfl_getdwarf.c \
+ $$PWD/dwfl_getmodules.c \
+ $$PWD/dwfl_getsrc.c \
+ $$PWD/dwfl_getsrclines.c \
+ $$PWD/dwfl_line_comp_dir.c \
+ $$PWD/dwfl_linecu.c \
+ $$PWD/dwfl_lineinfo.c \
+ $$PWD/dwfl_linemodule.c \
+ $$PWD/dwfl_module_addrdie.c \
+ $$PWD/dwfl_module_addrname.c \
+ $$PWD/dwfl_module_addrsym.c \
+ $$PWD/dwfl_module_build_id.c \
+ $$PWD/dwfl_module_dwarf_cfi.c \
+ $$PWD/dwfl_module_eh_cfi.c \
+ $$PWD/dwfl_module_getdwarf.c \
+ $$PWD/dwfl_module_getelf.c \
+ $$PWD/dwfl_module_getsrc_file.c \
+ $$PWD/dwfl_module_getsrc.c \
+ $$PWD/dwfl_module_getsym.c \
+ $$PWD/dwfl_module_info.c \
+ $$PWD/dwfl_module_nextcu.c \
+ $$PWD/dwfl_module_register_names.c \
+ $$PWD/dwfl_module_report_build_id.c \
+ $$PWD/dwfl_module_return_value_location.c \
+ $$PWD/dwfl_module.c \
+ $$PWD/dwfl_nextcu.c \
+ $$PWD/dwfl_onesrcline.c \
+ $$PWD/dwfl_report_elf.c \
+ $$PWD/dwfl_segment_report_module.c \
+ $$PWD/dwfl_validate_address.c \
+ $$PWD/dwfl_version.c \
+ $$PWD/elf-from-memory.c \
+ $$PWD/find-debuginfo.c \
+ $$PWD/frame_unwind.c \
+ $$PWD/gzip.c \
+ $$PWD/image-header.c \
+ $$PWD/libdwfl_crc32_file.c \
+ $$PWD/libdwfl_crc32.c \
+ $$PWD/lines.c \
+ $$PWD/link_map.c \
+ $$PWD/linux-core-attach.c \
+ $$PWD/linux-kernel-modules.c \
+ $$PWD/linux-pid-attach.c \
+ $$PWD/linux-proc-maps.c \
+ $$PWD/offline.c \
+ $$PWD/open.c \
+ $$PWD/relocate.c \
+ $$PWD/segment.c
diff --git a/3rdparty/elfutils/libdwfl/libdwflP.h b/3rdparty/elfutils/libdwfl/libdwflP.h
new file mode 100644
index 0000000..12ee116
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/libdwflP.h
@@ -0,0 +1,760 @@
+/* Internal definitions for libdwfl.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBDWFLP_H
+#define _LIBDWFLP_H 1
+
+#ifndef PACKAGE_NAME
+# include <config.h>
+#endif
+#include <libdwfl.h>
+#include <libebl.h>
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../libdw/libdwP.h" /* We need its INTDECLs. */
+#include "../libdwelf/libdwelfP.h"
+
+typedef struct Dwfl_Process Dwfl_Process;
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+#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 (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;
+
+struct Dwfl
+{
+ const Dwfl_Callbacks *callbacks;
+
+ 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. */
+
+ /* Cache from last dwfl_report_segment call. */
+ const void *lookup_tail_ident;
+ GElf_Off lookup_tail_vaddr;
+ GElf_Off lookup_tail_offset;
+ int lookup_tail_ndx;
+
+ char *executable_for_core; /* --executable if --core was specified. */
+};
+
+#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. */
+
+ 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;
+ /* The current frame being unwound. Initially it is the bottom frame.
+ Later the processed frames get freed and this pointer is updated. */
+ 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. */
+};
+
+
+/* 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
+{
+ DIR *dir;
+ /* 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;
+
+/* Internal 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. */
+extern const char *__libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr,
+ GElf_Off *off, GElf_Sym *sym,
+ GElf_Word *shndxp, Elf **elfp,
+ Dwarf_Addr *bias,
+ 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, off64_t start_offset,
+ void *mapped, size_t mapped_size,
+ void **whole, size_t *whole_size)
+ internal_function;
+extern Dwfl_Error __libdw_bunzip2 (int fd, off64_t start_offset,
+ void *mapped, size_t mapped_size,
+ void **whole, size_t *whole_size)
+ internal_function;
+extern Dwfl_Error __libdw_unlzma (int fd, off64_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, off64_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;
+
+/* 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;
+
+/* 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/3rdparty/elfutils/libdwfl/libdwfl_crc32.c b/3rdparty/elfutils/libdwfl/libdwfl_crc32.c
new file mode 100644
index 0000000..b89d0d3
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32 attribute_hidden __libdwfl_crc32
+#define LIB_SYSTEM_H 1
+#include <libdwflP.h>
+#include "../lib/crc32.c"
diff --git a/3rdparty/elfutils/libdwfl/libdwfl_crc32_file.c b/3rdparty/elfutils/libdwfl/libdwfl_crc32_file.c
new file mode 100644
index 0000000..6b6b7d3
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/libdwfl_crc32_file.c
@@ -0,0 +1,36 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32_file attribute_hidden __libdwfl_crc32_file
+#define crc32 __libdwfl_crc32
+#define LIB_SYSTEM_H 1
+#include <libdwflP.h>
+#include "../lib/crc32_file.c"
diff --git a/3rdparty/elfutils/libdwfl/lines.c b/3rdparty/elfutils/libdwfl/lines.c
new file mode 100644
index 0000000..721e29c
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/lines.c
@@ -0,0 +1,52 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libdwfl/link_map.c b/3rdparty/elfutils/libdwfl/link_map.c
new file mode 100644
index 0000000..eaf43b5
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/link_map.c
@@ -0,0 +1,1021 @@
+/* Report modules by examining dynamic linker data structures.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "libdwflP.h"
+#include "../libdw/memory-access.h"
+#include "system.h"
+
+#include <byteswap.h>
+#include <endian.h>
+#include <fcntl.h>
+
+/* 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)
+
+
+/* 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)
+{
+ const union
+ {
+ char buf[size];
+ Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
+ Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
+ } *u = auxv;
+
+ inline bool check64 (size_t i)
+ {
+ /* The AUXV pointer might not even be naturally aligned for 64-bit
+ data, because note payloads in a core file are not aligned.
+ But we assume the data is 32-bit aligned. */
+
+ uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
+ uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);
+
+ 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;
+ }
+
+ inline bool check32 (size_t i)
+ {
+ if (u->a32[i].a_type == BE32 (PROBE_TYPE)
+ && u->a32[i].a_un.a_val == BE32 (PROBE_VAL32))
+ {
+ *elfdata = ELFDATA2MSB;
+ return true;
+ }
+
+ if (u->a32[i].a_type == LE32 (PROBE_TYPE)
+ && u->a32[i].a_un.a_val == LE32 (PROBE_VAL32))
+ {
+ *elfdata = ELFDATA2LSB;
+ return true;
+ }
+
+ return false;
+ }
+
+ for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i)
+ {
+ if (check64 (i))
+ {
+ *elfclass = ELFCLASS64;
+ return true;
+ }
+
+ if (check32 (i * 2) || check32 (i * 2 + 1))
+ {
+ *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;
+}
+
+/* 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;
+ inline int release_buffer (int result)
+ {
+ if (buffer != NULL)
+ (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
+ memory_callback_arg);
+ return result;
+ }
+
+ GElf_Addr addrs[4];
+ inline bool read_addrs (GElf_Addr vaddr, size_t n)
+ {
+ size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read. */
+
+ /* 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 (0);
+
+ read_vaddr = vaddr;
+ int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL);
+ if (unlikely (segndx < 0)
+ || unlikely (! (*memory_callback) (dwfl, segndx,
+ &buffer, &buffer_available,
+ vaddr, nb, memory_callback_arg)))
+ return true;
+ }
+
+ const union
+ {
+ Elf32_Addr a32[n];
+ Elf64_Addr a64[n];
+ } *in = vaddr - read_vaddr + buffer;
+
+ if (elfclass == ELFCLASS32)
+ {
+ if (elfdata == ELFDATA2MSB)
+ for (size_t i = 0; i < n; ++i)
+ addrs[i] = BE32 (in->a32[i]);
+ else
+ for (size_t i = 0; i < n; ++i)
+ addrs[i] = LE32 (in->a32[i]);
+ }
+ else
+ {
+ if (elfdata == ELFDATA2MSB)
+ for (size_t i = 0; i < n; ++i)
+ addrs[i] = BE64 (in->a64[i]);
+ else
+ for (size_t i = 0; i < n; ++i)
+ addrs[i] = LE64 (in->a64[i]);
+ }
+
+ return false;
+ }
+
+ if (unlikely (read_addrs (read_vaddr, 1)))
+ return release_buffer (-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 (next, 4))
+ return release_buffer (-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 (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->executable_for_core != NULL)
+ name = dwfl->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 (r_debug_info_module == NULL)
+ return release_buffer (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 = open64 (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 (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 (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 (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) \
+ { \
+ uint##NN##_t type = READ_AUXV##NN (&av[i].a_type); \
+ uint##NN##_t val = BL##NN (READ_AUXV##NN (&av[i].a_un.a_val)); \
+ 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;
+
+ inline bool consider_phdr (GElf_Word type,
+ GElf_Addr vaddr, GElf_Xword filesz)
+ {
+ switch (type)
+ {
+ case 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;
+ return dyn_vaddr != 0;
+ }
+ break;
+
+ case PT_DYNAMIC:
+ dyn_vaddr = vaddr;
+ dyn_filesz = filesz;
+ return dyn_bias != (GElf_Addr) -1;
+ }
+
+ return false;
+ }
+
+ 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);
+ if (! in_ok && dwfl->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->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);
+ assert (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;
+ }
+ if (in_ok)
+ {
+ union
+ {
+ Elf32_Phdr p32;
+ Elf64_Phdr p64;
+ char data[phnum * phent];
+ } buf;
+ 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))
+ {
+ /* We are looking for PT_DYNAMIC. */
+ const union
+ {
+ Elf32_Phdr p32[phnum];
+ Elf64_Phdr p64[phnum];
+ } *u = (void *) &buf;
+ if (elfclass == ELFCLASS32)
+ {
+ for (size_t i = 0; i < phnum; ++i)
+ if (consider_phdr (u->p32[i].p_type,
+ u->p32[i].p_vaddr,
+ u->p32[i].p_filesz))
+ break;
+ }
+ else
+ {
+ for (size_t i = 0; i < phnum; ++i)
+ if (consider_phdr (u->p64[i].p_type,
+ u->p64[i].p_vaddr,
+ u->p64[i].p_filesz))
+ break;
+ }
+ }
+
+ (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
+ memory_callback_arg);
+ }
+ 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))
+ {
+ union
+ {
+ Elf32_Dyn d32;
+ Elf64_Dyn d64;
+ char data[dyn_filesz];
+ } buf;
+ 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. */
+ const union
+ {
+ Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
+ Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
+ } *u = (void *) &buf;
+ if (elfclass == ELFCLASS32)
+ {
+ size_t n = dyn_filesz / sizeof (Elf32_Dyn);
+ for (size_t i = 0; i < n; ++i)
+ if (u->d32[i].d_tag == DT_DEBUG)
+ {
+ r_debug_vaddr = u->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 (u->d64[i].d_tag == DT_DEBUG)
+ {
+ r_debug_vaddr = u->d64[i].d_un.d_val;
+ break;
+ }
+ }
+ }
+
+ (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
+ memory_callback_arg);
+ }
+ }
+ }
+ 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/3rdparty/elfutils/libdwfl/linux-core-attach.c b/3rdparty/elfutils/libdwfl/linux-core-attach.c
new file mode 100644
index 0000000..5a7b3b3
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/linux-core-attach.c
@@ -0,0 +1,427 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include "system.h"
+
+#include "../libdw/memory-access.h"
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+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 = 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,
+ &regs_offset, &nregloc, &reglocs, &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. */
+ assert (getnote_err != 0);
+ /* Do not check NAME for now, help broken Linux kernels. */
+ const char *name = 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, &regs_offset,
+ &nregloc, &reglocs, &nitems, &items);
+ /* __libdwfl_attach_state_for_core already verified the note is there. */
+ assert (core_note_err != 0);
+ assert (nhdr.n_type == NT_PRSTATUS);
+ 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, 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 = 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,
+ &regs_offset, &nregloc, &reglocs, &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/3rdparty/elfutils/libdwfl/linux-kernel-modules.c b/3rdparty/elfutils/libdwfl/linux-kernel-modules.c
new file mode 100644
index 0000000..e4065d8
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/linux-kernel-modules.c
@@ -0,0 +1,928 @@
+/* Standard libdwfl callbacks for debugging the running Linux kernel.
+ Copyright (C) 2005-2011, 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 <http://www.gnu.org/licenses/>. */
+
+/* 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. */
+
+#include <fts.h>
+
+#include <config.h>
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#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. */
+
+
+#if defined (USE_ZLIB) || defined (USE_BZLIB) || defined (USE_LZMA)
+static const char *vmlinux_suffixes[] =
+ {
+#ifdef USE_ZLIB
+ ".gz",
+#endif
+#ifdef USE_BZLIB
+ ".bz2",
+#endif
+#ifdef USE_LZMA
+ ".xz",
+#endif
+ };
+#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 (open64 (*fname, O_RDONLY)));
+
+ if (fd < 0)
+ {
+ Dwfl_Module fakemod = { .dwfl = dwfl };
+ /* First try the file's unadorned basename as DEBUGLINK_FILE,
+ to look for "vmlinux" files. */
+ fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
+ *fname, basename (*fname), 0,
+ &fakemod.debug.name);
+ if (fd < 0 && try_debug)
+ /* Next, let the call use 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);
+ if (fakemod.debug.name != NULL)
+ {
+ free (*fname);
+ *fname = fakemod.debug.name;
+ }
+ }
+
+#if defined (USE_ZLIB) || defined (USE_BZLIB) || defined (USE_LZMA)
+ if (fd < 0)
+ for (size_t i = 0;
+ i < sizeof vmlinux_suffixes / sizeof vmlinux_suffixes[0];
+ ++i)
+ {
+ char *zname;
+ if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0)
+ {
+ fd = TEMP_FAILURE_RETRY (open64 (zname, O_RDONLY));
+ if (fd < 0)
+ free (zname);
+ else
+ {
+ free (*fname);
+ *fname = zname;
+ }
+ }
+ }
+#endif
+
+ if (fd < 0)
+ {
+ free (*fname);
+ *fname = NULL;
+ }
+
+ return fd;
+}
+
+static inline const char *
+kernel_release (void)
+{
+ /* 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;
+}
+
+static int
+find_kernel_elf (Dwfl *dwfl, const char *release, char **fname)
+{
+ if ((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);
+ }
+
+ 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;
+
+ 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;
+
+ 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");
+#if USE_ZLIB
+ TRY (".ko.gz");
+#endif
+#if USE_BZLIB
+ TRY (".ko.bz2");
+#endif
+#if USE_LZMA
+ TRY (".ko.xz");
+#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[f->fts_namelen - suffix + 1];
+ for (size_t i = 0; i < f->fts_namelen - 3U; ++i)
+ if (f->fts_name[i] == '-' || f->fts_name[i] == ',')
+ name[i] = '_';
+ else
+ name[i] = f->fts_name[i];
+ name[f->fts_namelen - suffix] = '\0';
+
+ if (predicate != NULL)
+ {
+ /* Let the predicate decide whether to use this one. */
+ int want = (*predicate) (name, f->fts_path);
+ if (want < 0)
+ {
+ result = -1;
+ break;
+ }
+ if (!want)
+ continue;
+ }
+
+ if (dwfl_report_offline (dwfl, name, f->fts_path, -1) == NULL)
+ {
+ result = -1;
+ break;
+ }
+ }
+ 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)
+
+
+/* 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)
+{
+ FILE *f = fopen (KSYMSFILE, "r");
+ if (f == NULL)
+ return errno;
+
+ (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+ *notes = 0;
+
+ char *line = NULL;
+ size_t linesz = 0;
+ size_t n;
+ char *p = NULL;
+ const char *type;
+
+ inline bool read_address (Dwarf_Addr *addr)
+ {
+ if ((n = getline (&line, &linesz, f)) < 1 || line[n - 2] == ']')
+ return false;
+ *addr = strtoull (line, &p, 16);
+ p += strspn (p, " \t");
+ type = strsep (&p, " \t\n");
+ if (type == NULL)
+ return false;
+ return p != NULL && p != line;
+ }
+
+ int result;
+ do
+ result = read_address (start) ? 0 : -1;
+ while (result == 0 && strchr ("TtRr", *type) == NULL);
+
+ if (result == 0)
+ {
+ *end = *start;
+ while (read_address (end))
+ if (*notes == 0 && !strcmp (p, "__start_notes\n"))
+ *notes = *end;
+
+ Dwarf_Addr round_kernel = sysconf (_SC_PAGE_SIZE);
+ *start &= -(Dwarf_Addr) round_kernel;
+ *end += round_kernel - 1;
+ *end &= -(Dwarf_Addr) round_kernel;
+ if (*start >= *end || *end - *start < round_kernel)
+ result = -1;
+ }
+ free (line);
+
+ if (result == -1)
+ result = ferror_unlocked (f) ? errno : ENOEXEC;
+
+ fclose (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 = open64 (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;
+ while (p < &buf.data[n])
+ {
+ /* No translation required since we are reading the native kernel. */
+ GElf_Nhdr *nhdr = (void *) p;
+ p += sizeof *nhdr;
+ unsigned char *name = p;
+ p += (nhdr->n_namesz + 3) & -4U;
+ unsigned char *bits = p;
+ p += (nhdr->n_descsz + 3) & -4U;
+
+ 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;
+ Dwarf_Addr end;
+ inline Dwfl_Module *report (void)
+ {
+ return 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;
+ /* The compiler cannot deduce that if intuit_kernel_bounds returns
+ zero NOTES will be initialized. Fake the initialization. */
+ asm ("" : "=m" (notes));
+ int result = intuit_kernel_bounds (&start, &end, &notes);
+ 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)
+
+
+/* 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[namelen + 1];
+ inline bool subst_name (char from, char to)
+ {
+ 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;
+ }
+ if (!subst_name ('-', '_') && !subst_name ('_', '-'))
+ 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 = open64 (f->fts_accpath, O_RDONLY);
+ *file_name = strdup (f->fts_path);
+ fts_close (fts);
+ free (modulesdir[0]);
+ 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]);
+ 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")
+ || !strncmp (secname, ".exit", 5))
+ {
+ *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 = !strncmp (secname, ".init", 5);
+ 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/3rdparty/elfutils/libdwfl/linux-pid-attach.c b/3rdparty/elfutils/libdwfl/linux-pid-attach.c
new file mode 100644
index 0000000..ae71702
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/linux-pid-attach.c
@@ -0,0 +1,475 @@
+/* Get Dwarf Frame state for target live PID process.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifdef __linux__
+
+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 (strncmp (buffer, "State:", 6) == 0)
+ {
+ 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;
+}
+
+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;
+ assert (tid > 0);
+ Dwfl_Process *process = dwfl->process;
+ 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;
+ 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;
+ 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 (strncmp (line, "Tgid:", 5) == 0)
+ {
+ 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 dirname[64];
+ int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
+ assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
+ DIR *dir = opendir (dirname);
+ if (dir == NULL)
+ {
+ err = errno;
+ goto fail;
+ }
+ struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
+ if (pid_arg == NULL)
+ {
+ closedir (dir);
+ err = ENOMEM;
+ goto fail;
+ }
+ pid_arg->dir = dir;
+ pid_arg->tid_attached = 0;
+ pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
+ if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
+ pid_arg))
+ {
+ 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__ */
+
+static pid_t
+pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
+ void *dwfl_arg __attribute__ ((unused)),
+ void **thread_argp __attribute__ ((unused)))
+{
+ errno = ENOSYS;
+ __libdwfl_seterrno (DWFL_E_ERRNO);
+ return -1;
+}
+
+static bool
+pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
+ pid_t tid __attribute__ ((unused)),
+ void *dwfl_arg __attribute__ ((unused)),
+ void **thread_argp __attribute__ ((unused)))
+{
+ errno = ENOSYS;
+ __libdwfl_seterrno (DWFL_E_ERRNO);
+ return false;
+}
+
+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;
+}
+
+static bool
+pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
+ Dwarf_Addr addr __attribute__ ((unused)),
+ Dwarf_Word *result __attribute__ ((unused)),
+ void *arg __attribute__ ((unused)))
+{
+ errno = ENOSYS;
+ __libdwfl_seterrno (DWFL_E_ERRNO);
+ return false;
+}
+
+static bool
+pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
+ void *thread_arg __attribute__ ((unused)))
+{
+ errno = ENOSYS;
+ __libdwfl_seterrno (DWFL_E_ERRNO);
+ return false;
+}
+
+static void
+pid_detach (Dwfl *dwfl __attribute__ ((unused)),
+ void *dwfl_arg __attribute__ ((unused)))
+{
+}
+
+void
+internal_function
+__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
+ bool tid_was_stopped __attribute__ ((unused)))
+{
+}
+
+static void
+pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
+ void *thread_arg __attribute__ ((unused)))
+{
+}
+
+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 __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/3rdparty/elfutils/libdwfl/linux-proc-maps.c b/3rdparty/elfutils/libdwfl/linux-proc-maps.c
new file mode 100644
index 0000000..d085834
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/linux-proc-maps.c
@@ -0,0 +1,422 @@
+/* Standard libdwfl callbacks for debugging a live Linux process.
+ Copyright (C) 2005-2010, 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <endian.h>
+#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 = open64 (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 = open64 (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 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;
+
+ inline bool report (void)
+ {
+ if (last_file != NULL)
+ {
+ Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, last_file,
+ low, high);
+ free (last_file);
+ last_file = NULL;
+ if (unlikely (mod == NULL))
+ return true;
+ }
+ return false;
+ }
+
+ 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 %" PRIi64 " %n",
+ &start, &end, &offset, &dmajor, &dminor, &ino, &nread) < 6
+ || nread <= 0)
+ {
+ free (line);
+ 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)
+ 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;
+ ssize_t nread = pread64 (fd, data, maxread, (off64_t) address);
+ /* Some kernels don't actually let us do this read, ignore those errors. */
+ if (nread < 0 && (errno == EINVAL || errno == EPERM))
+ return 0;
+ 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 = open64 (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 = open64 (fname, O_RDONLY);
+ free (fname);
+ if (fd < 0)
+ goto detach;
+
+ *elfp = elf_from_remote_memory (base, getpagesize (), 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/3rdparty/elfutils/libdwfl/offline.c b/3rdparty/elfutils/libdwfl/offline.c
new file mode 100644
index 0000000..982ceab
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/offline.c
@@ -0,0 +1,311 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+/* 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)
+ {
+ 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 = open64 (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/3rdparty/elfutils/libdwfl/open.c b/3rdparty/elfutils/libdwfl/open.c
new file mode 100644
index 0000000..40aac38
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/open.c
@@ -0,0 +1,182 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "../libelf/libelfP.h"
+#undef _
+#include "libdwflP.h"
+
+#include <unistd.h>
+
+#if !USE_ZLIB
+# define __libdw_gunzip(...) DWFL_E_BADELF
+#endif
+
+#if !USE_BZLIB
+# define __libdw_bunzip2(...) DWFL_E_BADELF
+#endif
+
+#if !USE_LZMA
+# define __libdw_unlzma(...) 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;
+
+#if USE_ZLIB || USE_BZLIB || USE_LZMA
+ const off64_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);
+#endif
+
+ 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 *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)
+ {
+ *close_fd = true;
+ *kind = elf_kind (*elfp);
+ }
+ }
+ }
+ return error;
+}
+
+Dwfl_Error internal_function
+__libdw_open_file (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok)
+{
+ bool 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, &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. */
+
+ off64_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, &close_fd);
+ }
+ }
+ }
+
+ if (error == DWFL_E_NOERROR
+ && kind != ELF_K_ELF
+ && !(archive_ok && kind == ELF_K_AR))
+ error = DWFL_E_BADELF;
+
+ if (error != DWFL_E_NOERROR)
+ {
+ elf_end (elf);
+ elf = NULL;
+ }
+
+ if (error == DWFL_E_NOERROR ? close_fd : close_on_fail)
+ {
+ close (*fdp);
+ *fdp = -1;
+ }
+
+ *elfp = elf;
+ return error;
+}
diff --git a/3rdparty/elfutils/libdwfl/relocate.c b/3rdparty/elfutils/libdwfl/relocate.c
new file mode 100644
index 0000000..e102e1e
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/relocate.c
@@ -0,0 +1,683 @@
+/* Relocate debug information.
+ Copyright (C) 2005-2011, 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 <http://www.gnu.org/licenses/>. */
+
+#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)
+ 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);
+ symtab->symstrdata = elf_getdata (elf_getscn (symtab->symelf,
+ symtab->strtabndx),
+ 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;
+}
+
+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. */
+ GElf_Shdr tshdr_mem;
+ GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
+ const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name);
+ if (tname == 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;
+
+ 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;
+
+ /* 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. */
+ 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)
+ || (shdrs_start < tshdr->sh_offset + tshdr->sh_size
+ && tshdr->sh_offset < shdrs_end)))
+ 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)
+ || (phdrs_start < tshdr->sh_offset + tshdr->sh_size
+ && tshdr->sh_offset < phdrs_end)))
+ return DWFL_E_BADELF;
+ }
+
+ /* Apply one relocation. Returns true for any invalid data. */
+ Dwfl_Error relocate (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;
+
+ Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
+ 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: \
+ 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;
+ switch (type)
+ {
+#define DO_TYPE(NAME, Name) \
+ case ELF_T_##NAME: \
+ 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;
+ }
+
+ /* 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;
+ inline void check_badreltype (void)
+ {
+ 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;
+ }
+ }
+
+ 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 (r->r_offset, NULL,
+ GELF_R_TYPE (r->r_info),
+ GELF_R_SYM (r->r_info));
+ check_badreltype ();
+ if (partial)
+ switch (result)
+ {
+ case DWFL_E_NOERROR:
+ /* We applied the relocation. Elide it. */
+ memset (&rel_mem, 0, sizeof rel_mem);
+ gelf_update_rel (reldata, relidx, &rel_mem);
+ ++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 (r->r_offset, &r->r_addend,
+ GELF_R_TYPE (r->r_info),
+ GELF_R_SYM (r->r_info));
+ check_badreltype ();
+ if (partial)
+ switch (result)
+ {
+ case DWFL_E_NOERROR:
+ /* We applied the relocation. Elide it. */
+ memset (&rela_mem, 0, sizeof rela_mem);
+ gelf_update_rela (reldata, relidx, &rela_mem);
+ ++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 (r->r_info != 0 || r->r_offset != 0)
+ {
+ if (next != relidx)
+ gelf_update_rel (reldata, next, r);
+ ++next;
+ }
+ }
+ else
+ for (size_t relidx = 0; relidx < nrels; ++relidx)
+ {
+ GElf_Rela rela_mem;
+ GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
+ if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0)
+ {
+ if (next != relidx)
+ gelf_update_rela (reldata, next, r);
+ ++next;
+ }
+ }
+ nrels = next;
+ }
+
+ shdr->sh_size = reldata->d_size = nrels * sh_entsize;
+ gelf_update_shdr (scn, shdr);
+ }
+
+ 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 ((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, !debug);
+ }
+ }
+
+ 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;
+
+ return (__libdwfl_module_getebl (mod)
+ ?: relocate_section (mod, relocated,
+ gelf_getehdr (relocated, &ehdr_mem), shstrndx,
+ &reloc_symtab,
+ relocscn, gelf_getshdr (relocscn, &shdr_mem),
+ tscn, false, partial));
+}
diff --git a/3rdparty/elfutils/libdwfl/segment.c b/3rdparty/elfutils/libdwfl/segment.c
new file mode 100644
index 0000000..9276917
--- /dev/null
+++ b/3rdparty/elfutils/libdwfl/segment.c
@@ -0,0 +1,332 @@
+/* Manage address space lookup table for libdwfl.
+ Copyright (C) 2008, 2009, 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 <http://www.gnu.org/licenses/>. */
+
+#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 >= 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)
+{
+ if (dwfl == NULL)
+ return -1;
+
+ if (ndx < 0)
+ ndx = dwfl->lookup_tail_ndx;
+
+ 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);
+
+ /* Coalesce into the last one if contiguous and matching. */
+ if (ndx != dwfl->lookup_tail_ndx
+ || ident == NULL
+ || ident != dwfl->lookup_tail_ident
+ || start != dwfl->lookup_tail_vaddr
+ || phdr->p_offset != dwfl->lookup_tail_offset)
+ {
+ /* 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->lookup_tail_ident = ident;
+ dwfl->lookup_tail_vaddr = end;
+ dwfl->lookup_tail_offset = end - bias - phdr->p_vaddr + phdr->p_offset;
+ dwfl->lookup_tail_ndx = ndx + 1;
+
+ return ndx;
+}
+INTDEF (dwfl_report_segment)
diff --git a/3rdparty/elfutils/libebl/ebl-hooks.h b/3rdparty/elfutils/libebl/ebl-hooks.h
new file mode 100644
index 0000000..2e31446
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebl-hooks.h
@@ -0,0 +1,195 @@
+/* Backend hook signatures internal interface for libebl.
+ Copyright (C) 2000-2011, 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 <http://www.gnu.org/licenses/>. */
+
+/* Return symbol representaton of object file type. */
+const char *EBLHOOK(object_type_name) (int, char *, size_t);
+
+/* 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);
+
+/* 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);
+
+/* Combine section header flags values. */
+GElf_Word EBLHOOK(sh_flags_combine) (GElf_Word, GElf_Word);
+
+/* 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 *, GElf_Ehdr *, const GElf_Sym *,
+ const char *, const GElf_Shdr *);
+
+/* 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);
+
+/* Return system call ABI registers. */
+int EBLHOOK(syscall_abi) (Ebl *ebl, int *sp, int *pc,
+ int *callno, int args[6]);
+
+/* Disassembler function. */
+int EBLHOOK(disasm) (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/3rdparty/elfutils/libebl/ebl_check_special_section.c b/3rdparty/elfutils/libebl/ebl_check_special_section.c
new file mode 100644
index 0000000..aabe44e
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebl_check_special_section.c
@@ -0,0 +1,44 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_check_special_section (ebl, ndx, shdr, sname)
+ 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/3rdparty/elfutils/libebl/ebl_check_special_symbol.c b/3rdparty/elfutils/libebl/ebl_check_special_symbol.c
new file mode 100644
index 0000000..8e702ba
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebl_check_special_symbol.c
@@ -0,0 +1,49 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_check_special_symbol (ebl, ehdr, sym, name, destshdr)
+ Ebl *ebl;
+ GElf_Ehdr *ehdr;
+ const GElf_Sym *sym;
+ const char *name;
+ const GElf_Shdr *destshdr;
+{
+ if (ebl == NULL)
+ return false;
+
+ return ebl->check_special_symbol (ebl->elf, ehdr, sym, name, destshdr);
+}
diff --git a/3rdparty/elfutils/libebl/ebl_syscall_abi.c b/3rdparty/elfutils/libebl/ebl_syscall_abi.c
new file mode 100644
index 0000000..de73703
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebl_syscall_abi.c
@@ -0,0 +1,45 @@
+/* Return system call ABI mapped to DWARF register numbers.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_syscall_abi (ebl, sp, pc, callno, args)
+ Ebl *ebl;
+ int *sp;
+ int *pc;
+ int *callno;
+ int args[6];
+{
+ return ebl != NULL ? ebl->syscall_abi (ebl, sp, pc, callno, args) : -1;
+}
diff --git a/3rdparty/elfutils/libebl/eblabicfi.c b/3rdparty/elfutils/libebl/eblabicfi.c
new file mode 100644
index 0000000..20a29ea
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblabicfi.c
@@ -0,0 +1,42 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_abi_cfi (ebl, abi_info)
+ Ebl *ebl;
+ Dwarf_CIE *abi_info;
+{
+ return ebl == NULL ? -1 : ebl->abi_cfi (ebl, abi_info);
+}
diff --git a/3rdparty/elfutils/libebl/eblauxvinfo.c b/3rdparty/elfutils/libebl/eblauxvinfo.c
new file mode 100644
index 0000000..5c310b2
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblauxvinfo.c
@@ -0,0 +1,103 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <libeblP.h>
+
+#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, a_type, name, format)
+ 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/3rdparty/elfutils/libebl/eblbackendname.c b/3rdparty/elfutils/libebl/eblbackendname.c
new file mode 100644
index 0000000..92e576e
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblbackendname.c
@@ -0,0 +1,43 @@
+/* Return backend name.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_backend_name (ebl)
+ Ebl *ebl;
+{
+ return ebl != NULL ? ebl->emulation : gettext ("No backend");
+}
diff --git a/3rdparty/elfutils/libebl/eblbsspltp.c b/3rdparty/elfutils/libebl/eblbsspltp.c
new file mode 100644
index 0000000..95a5d8a
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblbsspltp.c
@@ -0,0 +1,42 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_bss_plt_p (ebl)
+ Ebl *ebl;
+{
+ return ebl == NULL ? false : ebl->bss_plt_p (ebl->elf);
+}
diff --git a/3rdparty/elfutils/libebl/eblcheckobjattr.c b/3rdparty/elfutils/libebl/eblcheckobjattr.c
new file mode 100644
index 0000000..b0481d2
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblcheckobjattr.c
@@ -0,0 +1,60 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <libeblP.h>
+
+
+bool
+ebl_check_object_attribute (ebl, vendor, tag, value, tag_name, value_name)
+ 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/3rdparty/elfutils/libebl/eblcheckreloctargettype.c b/3rdparty/elfutils/libebl/eblcheckreloctargettype.c
new file mode 100644
index 0000000..e135f8a
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblcheckreloctargettype.c
@@ -0,0 +1,46 @@
+/* Check whether a section type is a valid target for relocation.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type)
+{
+ if (ebl->check_reloc_target_type (ebl, sh_type))
+ return true;
+
+ if (sh_type == SHT_PROGBITS || sh_type == SHT_NOBITS)
+ return true;
+
+ return false;
+}
diff --git a/3rdparty/elfutils/libebl/eblclosebackend.c b/3rdparty/elfutils/libebl/eblclosebackend.c
new file mode 100644
index 0000000..67fbdfe
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblclosebackend.c
@@ -0,0 +1,54 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include <libeblP.h>
+
+
+void
+ebl_closebackend (Ebl *ebl)
+{
+ if (ebl != NULL)
+ {
+ /* Run the destructor. */
+ ebl->destr (ebl);
+
+ /* Close the dynamically loaded object. */
+ if (ebl->dlhandle != NULL)
+ (void) dlclose (ebl->dlhandle);
+
+ /* Free the resources. */
+ free (ebl);
+ }
+}
diff --git a/3rdparty/elfutils/libebl/eblcopyrelocp.c b/3rdparty/elfutils/libebl/eblcopyrelocp.c
new file mode 100644
index 0000000..702f8c7
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblcopyrelocp.c
@@ -0,0 +1,43 @@
+/* Check whether given relocation is a copy relocation.
+ Copyright (C) 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_copy_reloc_p (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl->copy_reloc_p (reloc);
+}
diff --git a/3rdparty/elfutils/libebl/eblcorenote.c b/3rdparty/elfutils/libebl/eblcorenote.c
new file mode 100644
index 0000000..2a79278
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblcorenote.c
@@ -0,0 +1,86 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <libeblP.h>
+
+
+int
+ebl_core_note (ebl, nhdr, name,
+ regs_offset, nregloc, reglocs, nitems, items)
+ Ebl *ebl;
+ 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;
+{
+ 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. */
+
+ *regs_offset = 0;
+ *nregloc = 0;
+ *reglocs = NULL;
+ switch (nhdr->n_type)
+ {
+#define ITEMS(type, table) \
+ case type: \
+ *items = table; \
+ *nitems = sizeof table / sizeof table[0]; \
+ result = 1; \
+ break
+
+ static const Ebl_Core_Item platform[] =
+ {
+ {
+ .name = "Platform",
+ .type = ELF_T_BYTE, .count = 0, .format = 's'
+ }
+ };
+ ITEMS (NT_PLATFORM, platform);
+
+#undef ITEMS
+ }
+ }
+
+ return result;
+}
diff --git a/3rdparty/elfutils/libebl/eblcorenotetypename.c b/3rdparty/elfutils/libebl/eblcorenotetypename.c
new file mode 100644
index 0000000..b6db6cd
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblcorenotetypename.c
@@ -0,0 +1,109 @@
+/* Return note type name.
+ Copyright (C) 2002, 2007, 2008, 2012, 2013 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+const char *
+ebl_core_note_type_name (ebl, type, buf, len)
+ 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 (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 (SIGINFO);
+ KNOWNSTYPE (FILE);
+#undef KNOWNSTYPE
+
+ default:
+ snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/ebldebugscnp.c b/3rdparty/elfutils/libebl/ebldebugscnp.c
new file mode 100644
index 0000000..01a5675
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebldebugscnp.c
@@ -0,0 +1,44 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdint.h>
+#include <libeblP.h>
+
+
+bool
+ebl_debugscn_p (ebl, name)
+ Ebl *ebl;
+ const char *name;
+{
+ return name != NULL && ebl->debugscn_p (name);
+}
diff --git a/3rdparty/elfutils/libebl/ebldwarftoregno.c b/3rdparty/elfutils/libebl/ebldwarftoregno.c
new file mode 100644
index 0000000..8fb8540
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebldwarftoregno.c
@@ -0,0 +1,41 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+bool
+ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno)
+{
+ if (ebl == NULL)
+ return false;
+ return ebl->dwarf_to_regno == NULL ? true : ebl->dwarf_to_regno (ebl, regno);
+}
diff --git a/3rdparty/elfutils/libebl/ebldynamictagcheck.c b/3rdparty/elfutils/libebl/ebldynamictagcheck.c
new file mode 100644
index 0000000..17acee0
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebldynamictagcheck.c
@@ -0,0 +1,56 @@
+/* Check dynamic tag.
+ Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_dynamic_tag_check (ebl, tag)
+ 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/3rdparty/elfutils/libebl/ebldynamictagname.c b/3rdparty/elfutils/libebl/ebldynamictagname.c
new file mode 100644
index 0000000..6b09ee6
--- /dev/null
+++ b/3rdparty/elfutils/libebl/ebldynamictagname.c
@@ -0,0 +1,113 @@
+/* Return dynamic tag name.
+ Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_dynamic_tag_name (ebl, tag, buf, len)
+ 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"
+ };
+
+ 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, gettext ("<unknown>: %#" PRIx64), tag);
+
+ res = buf;
+
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblelfclass.c b/3rdparty/elfutils/libebl/eblelfclass.c
new file mode 100644
index 0000000..62d1283
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblelfclass.c
@@ -0,0 +1,42 @@
+/* Return ELF class.
+ Copyright (C) 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfclass (ebl)
+ Ebl *ebl;
+{
+ return ebl->class;
+}
diff --git a/3rdparty/elfutils/libebl/eblelfdata.c b/3rdparty/elfutils/libebl/eblelfdata.c
new file mode 100644
index 0000000..b09dbb5
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblelfdata.c
@@ -0,0 +1,42 @@
+/* Return ELF data encoding.
+ Copyright (C) 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfdata (ebl)
+ Ebl *ebl;
+{
+ return ebl->data;
+}
diff --git a/3rdparty/elfutils/libebl/eblelfmachine.c b/3rdparty/elfutils/libebl/eblelfmachine.c
new file mode 100644
index 0000000..cd961e7
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblelfmachine.c
@@ -0,0 +1,42 @@
+/* Return ELF machine.
+ Copyright (C) 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfmachine (ebl)
+ Ebl *ebl;
+{
+ return ebl->machine;
+}
diff --git a/3rdparty/elfutils/libebl/eblgotpcreloccheck.c b/3rdparty/elfutils/libebl/eblgotpcreloccheck.c
new file mode 100644
index 0000000..55625de
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblgotpcreloccheck.c
@@ -0,0 +1,44 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_gotpc_reloc_check (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl != NULL ? ebl->gotpc_reloc_check (ebl->elf, reloc) : false;
+}
diff --git a/3rdparty/elfutils/libebl/eblgstrtab.c b/3rdparty/elfutils/libebl/eblgstrtab.c
new file mode 100644
index 0000000..0d92c00
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblgstrtab.c
@@ -0,0 +1,365 @@
+/* Generic string table handling.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include "libebl.h"
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+struct Ebl_GStrent
+{
+ const char *string;
+ size_t len;
+ struct Ebl_GStrent *next;
+ struct Ebl_GStrent *left;
+ struct Ebl_GStrent *right;
+ size_t offset;
+ unsigned int width;
+ char reverse[0];
+};
+
+
+struct memoryblock
+{
+ struct memoryblock *next;
+ char memory[0];
+};
+
+
+struct Ebl_GStrtab
+{
+ struct Ebl_GStrent *root;
+ struct memoryblock *memory;
+ char *backp;
+ size_t left;
+ size_t total;
+ unsigned int width;
+ bool nullstr;
+
+ struct Ebl_GStrent null;
+};
+
+
+/* Cache for the pagesize. We correct this value a bit so that `malloc'
+ is not allocating more than a page. */
+static size_t ps;
+
+
+struct Ebl_GStrtab *
+ebl_gstrtabinit (unsigned int width, bool nullstr)
+{
+ struct Ebl_GStrtab *ret;
+
+ if (ps == 0)
+ {
+ ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *);
+ assert (sizeof (struct memoryblock) < ps);
+ }
+
+ ret = (struct Ebl_GStrtab *) calloc (1, sizeof (struct Ebl_GStrtab));
+ if (ret != NULL)
+ {
+ ret->width = width;
+ ret->nullstr = nullstr;
+
+ if (nullstr)
+ {
+ ret->null.len = 1;
+ ret->null.string = (char *) calloc (1, width);
+ }
+ }
+
+ return ret;
+}
+
+
+static void
+morememory (struct Ebl_GStrtab *st, size_t len)
+{
+ struct memoryblock *newmem;
+
+ if (len < ps)
+ len = ps;
+ newmem = (struct memoryblock *) malloc (len);
+ if (newmem == NULL)
+ abort ();
+
+ newmem->next = st->memory;
+ st->memory = newmem;
+ st->backp = newmem->memory;
+ st->left = len - offsetof (struct memoryblock, memory);
+}
+
+
+void
+ebl_gstrtabfree (struct Ebl_GStrtab *st)
+{
+ struct memoryblock *mb = st->memory;
+
+ while (mb != NULL)
+ {
+ void *old = mb;
+ mb = mb->next;
+ free (old);
+ }
+
+ if (st->null.string != NULL)
+ free ((char *) st->null.string);
+
+ free (st);
+}
+
+
+static struct Ebl_GStrent *
+newstring (struct Ebl_GStrtab *st, const char *str, size_t len)
+{
+ /* Compute the amount of padding needed to make the structure aligned. */
+ size_t align = ((__alignof__ (struct Ebl_GStrent)
+ - (((uintptr_t) st->backp)
+ & (__alignof__ (struct Ebl_GStrent) - 1)))
+ & (__alignof__ (struct Ebl_GStrent) - 1));
+
+ /* Make sure there is enough room in the memory block. */
+ if (st->left < align + sizeof (struct Ebl_GStrent) + len * st->width)
+ {
+ morememory (st, sizeof (struct Ebl_GStrent) + len * st->width);
+ align = 0;
+ }
+
+ /* Create the reserved string. */
+ struct Ebl_GStrent *newstr = (struct Ebl_GStrent *) (st->backp + align);
+ newstr->string = str;
+ newstr->len = len;
+ newstr->width = st->width;
+ newstr->next = NULL;
+ newstr->left = NULL;
+ newstr->right = NULL;
+ newstr->offset = 0;
+ for (int i = len - 2; i >= 0; --i)
+ for (int j = st->width - 1; j >= 0; --j)
+ newstr->reverse[i * st->width + j] = str[(len - 2 - i) * st->width + j];
+ for (size_t j = 0; j < st->width; ++j)
+ newstr->reverse[(len - 1) * st->width + j] = '\0';
+ st->backp += align + sizeof (struct Ebl_GStrent) + len * st->width;
+ st->left -= align + sizeof (struct Ebl_GStrent) + len * st->width;
+
+ return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+ tree algorith (AVL, red-black trees). For now a simple, correct
+ implementation is enough. */
+static struct Ebl_GStrent **
+searchstring (struct Ebl_GStrent **sep, struct Ebl_GStrent *newstr)
+{
+ int cmpres;
+
+ /* More strings? */
+ if (*sep == NULL)
+ {
+ *sep = newstr;
+ return sep;
+ }
+
+ /* Compare the strings. */
+ cmpres = memcmp ((*sep)->reverse, newstr->reverse,
+ (MIN ((*sep)->len, newstr->len) - 1) * (*sep)->width);
+ 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. */
+struct Ebl_GStrent *
+ebl_gstrtabadd (struct Ebl_GStrtab *st, const char *str, size_t len)
+{
+ struct Ebl_GStrent *newstr;
+ struct Ebl_GStrent **sep;
+
+ /* Compute the string length if the caller doesn't know it. */
+ if (len == 0)
+ {
+ size_t j;
+
+ do
+ for (j = 0; j < st->width; ++j)
+ if (str[len * st->width + j] != '\0')
+ break;
+ while (j == st->width && ++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. */
+ newstr = newstring (st, str, len);
+
+ /* 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. */
+ 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)
+ {
+ struct Ebl_GStrent *subs;
+
+ /* Check whether we already know this string. */
+ for (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->width;
+ 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->width;
+ st->backp = (char *) newstr;
+
+ newstr = *sep;
+ }
+ }
+ else
+ st->total += newstr->len;
+
+ return newstr;
+}
+
+
+static void
+copystrings (struct Ebl_GStrent *nodep, char **freep, size_t *offsetp)
+{
+ struct Ebl_GStrent *subs;
+
+ if (nodep->left != NULL)
+ copystrings (nodep->left, freep, offsetp);
+
+ /* Process the current node. */
+ nodep->offset = *offsetp;
+ *freep = (char *) mempcpy (*freep, nodep->string, nodep->len * nodep->width);
+ *offsetp += nodep->len * nodep->width;
+
+ for (subs = nodep->next; subs != NULL; subs = subs->next)
+ {
+ assert (subs->len < nodep->len);
+ subs->offset = nodep->offset + (nodep->len - subs->len) * nodep->width;
+ assert (subs->offset != 0 || subs->string[0] == '\0');
+ }
+
+ if (nodep->right != NULL)
+ copystrings (nodep->right, freep, offsetp);
+}
+
+
+void
+ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data)
+{
+ size_t copylen;
+ char *endp;
+ size_t nulllen = st->nullstr ? st->width : 0;
+
+ /* Fill in the information. */
+ data->d_buf = malloc (st->total + nulllen);
+ if (data->d_buf == NULL)
+ abort ();
+
+ /* The first byte must always be zero if we created the table with a
+ null string. */
+ if (st->nullstr)
+ memset (data->d_buf, '\0', st->width);
+
+ 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. */
+ endp = (char *) data->d_buf + nulllen;
+ copylen = nulllen;
+ copystrings (st->root, &endp, &copylen);
+ assert (copylen == st->total * st->width + nulllen);
+}
+
+
+size_t
+ebl_gstrtaboffset (struct Ebl_GStrent *se)
+{
+ return se->offset;
+}
diff --git a/3rdparty/elfutils/libebl/eblheaders.pri b/3rdparty/elfutils/libebl/eblheaders.pri
new file mode 100644
index 0000000..71168fd
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblheaders.pri
@@ -0,0 +1,10 @@
+include(../libasm/asmheaders.pri)
+include(../libdw/dwheaders.pri)
+include(../libelf/elfheaders.pri)
+
+HEADERS += \
+ $$PWD/ebl-hooks.h \
+ $$PWD/libebl.h \
+ $$PWD/libeblP.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/libebl/eblinitreg.c b/3rdparty/elfutils/libebl/eblinitreg.c
new file mode 100644
index 0000000..5729b3c
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblinitreg.c
@@ -0,0 +1,58 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+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)
+{
+ return ebl == NULL ? 0 : 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/3rdparty/elfutils/libebl/eblmachineflagcheck.c b/3rdparty/elfutils/libebl/eblmachineflagcheck.c
new file mode 100644
index 0000000..d6d7931
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblmachineflagcheck.c
@@ -0,0 +1,43 @@
+/* Check machine flag.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_machine_flag_check (ebl, flags)
+ Ebl *ebl;
+ Elf64_Word flags;
+{
+ return ebl != NULL ? ebl->machine_flag_check (flags) : (flags == 0);
+}
diff --git a/3rdparty/elfutils/libebl/eblmachineflagname.c b/3rdparty/elfutils/libebl/eblmachineflagname.c
new file mode 100644
index 0000000..e392f5a
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblmachineflagname.c
@@ -0,0 +1,91 @@
+/* Return machine flag names.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_machine_flag_name (ebl, flags, buf, len)
+ 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/3rdparty/elfutils/libebl/eblmachinesectionflagcheck.c b/3rdparty/elfutils/libebl/eblmachinesectionflagcheck.c
new file mode 100644
index 0000000..671eb8c
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblmachinesectionflagcheck.c
@@ -0,0 +1,42 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_machine_section_flag_check (ebl, flags)
+ Ebl *ebl;
+ GElf_Xword flags;
+{
+ return ebl != NULL ? ebl->machine_section_flag_check (flags) : (flags == 0);
+}
diff --git a/3rdparty/elfutils/libebl/eblnonerelocp.c b/3rdparty/elfutils/libebl/eblnonerelocp.c
new file mode 100644
index 0000000..07c6b0e
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblnonerelocp.c
@@ -0,0 +1,43 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_none_reloc_p (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl->none_reloc_p (reloc);
+}
diff --git a/3rdparty/elfutils/libebl/eblnormalizepc.c b/3rdparty/elfutils/libebl/eblnormalizepc.c
new file mode 100644
index 0000000..a5fea77
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblnormalizepc.c
@@ -0,0 +1,40 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+void
+ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc)
+{
+ if (ebl != NULL && ebl->normalize_pc != NULL)
+ ebl->normalize_pc (ebl, pc);
+}
diff --git a/3rdparty/elfutils/libebl/eblobjecttypename.c b/3rdparty/elfutils/libebl/eblobjecttypename.c
new file mode 100644
index 0000000..1a2c8e8
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblobjecttypename.c
@@ -0,0 +1,63 @@
+/* Return object file type name.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_object_type_name (ebl, object, buf, len)
+ Ebl *ebl;
+ int object;
+ char *buf;
+ size_t len;
+{
+ const char *res;
+
+ res = ebl != NULL ? ebl->object_type_name (object, buf, len) : NULL;
+ if (res == NULL)
+ {
+ /* Handle OS-specific section names. */
+ if (object >= ET_LOOS && object <= ET_HIOS)
+ snprintf (buf, len, "LOOS+%x", object - ET_LOOS);
+ /* Handle processor-specific section names. */
+ else if (object >= ET_LOPROC && object <= ET_HIPROC)
+ snprintf (buf, len, "LOPROC+%x", object - ET_LOPROC);
+ else
+ snprintf (buf, len, "%s: %d", gettext ("<unknown>"), object);
+
+ res = buf;
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblobjnote.c b/3rdparty/elfutils/libebl/eblobjnote.c
new file mode 100644
index 0000000..d1fe821
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblobjnote.c
@@ -0,0 +1,220 @@
+/* Print contents of object file note.
+ Copyright (C) 2002, 2007, 2009, 2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+void
+ebl_object_note (ebl, name, type, descsz, desc)
+ Ebl *ebl;
+ 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 (gettext ("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 (gettext ("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 (gettext (" PC: "));
+ printf ("%#" PRIx64 ",", pc);
+ printf (gettext (" Base: "));
+ printf ("%#" PRIx64 ",", base);
+ printf (gettext (" Semaphore: "));
+ printf ("%#" PRIx64 "\n", sem);
+ printf (gettext (" Provider: "));
+ printf ("%s,", provider);
+ printf (gettext (" Name: "));
+ printf ("%s,", pname);
+ printf (gettext (" Args: "));
+ printf ("'%s'\n", args);
+ return;
+ }
+
+ switch (type)
+ {
+ case NT_GNU_BUILD_ID:
+ if (strcmp (name, "GNU") == 0 && descsz > 0)
+ {
+ printf (gettext (" 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 (gettext (" Linker version: %.*s\n"),
+ (int) descsz, desc);
+ break;
+
+ case NT_GNU_ABI_TAG:
+ if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0)
+ {
+ Elf_Data in =
+ {
+ .d_version = EV_CURRENT,
+ .d_type = ELF_T_WORD,
+ .d_size = descsz,
+ .d_buf = (void *) desc
+ };
+ uint32_t buf[descsz / 4];
+ 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 (gettext (" 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');
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ /* Unknown type. */
+ break;
+ }
+}
diff --git a/3rdparty/elfutils/libebl/eblobjnotetypename.c b/3rdparty/elfutils/libebl/eblobjnotetypename.c
new file mode 100644
index 0000000..8a70e61
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblobjnotetypename.c
@@ -0,0 +1,80 @@
+/* Return note type name.
+ Copyright (C) 2002, 2007, 2009, 2011 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_object_note_type_name (ebl, name, type, buf, len)
+ Ebl *ebl;
+ const char *name;
+ uint32_t type;
+ 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;
+ }
+
+ static const char *knowntypes[] =
+ {
+#define KNOWNSTYPE(name) [NT_##name] = #name
+ KNOWNSTYPE (VERSION),
+ KNOWNSTYPE (GNU_HWCAP),
+ KNOWNSTYPE (GNU_BUILD_ID),
+ KNOWNSTYPE (GNU_GOLD_VERSION),
+ };
+
+ /* Handle standard names. */
+ if (type < sizeof (knowntypes) / sizeof (knowntypes[0])
+ && knowntypes[type] != NULL)
+ res = knowntypes[type];
+ else
+ {
+ snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblopenbackend.c b/3rdparty/elfutils/libebl/eblopenbackend.c
new file mode 100644
index 0000000..3a22f53
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblopenbackend.c
@@ -0,0 +1,763 @@
+/* Generate ELF backend handle.
+ Copyright (C) 2000-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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <error.h>
+#include <libelfP.h>
+#include <dwarf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <libeblP.h>
+
+
+/* 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
+{
+ const char *dsoname;
+ const char *emulation;
+ const char *prefix;
+ int prefix_len;
+ int em;
+ int class;
+ int data;
+} machines[] =
+{
+ { "i386", "elf_i386", "i386", 4, EM_386, ELFCLASS32, ELFDATA2LSB },
+ { "ia64", "elf_ia64", "ia64", 4, EM_IA_64, ELFCLASS64, ELFDATA2LSB },
+ { "alpha", "elf_alpha", "alpha", 5, EM_ALPHA, ELFCLASS64, ELFDATA2LSB },
+ { "x86_64", "elf_x86_64", "x86_64", 6, EM_X86_64, ELFCLASS64, ELFDATA2LSB },
+ { "ppc", "elf_ppc", "ppc", 3, EM_PPC, ELFCLASS32, ELFDATA2MSB },
+ { "ppc64", "elf_ppc64", "ppc64", 5, EM_PPC64, ELFCLASS64, ELFDATA2MSB },
+ { "tilegx", "elf_tilegx", "tilegx", 6, EM_TILEGX, ELFCLASS64, ELFDATA2LSB },
+ // XXX class and machine fields need to be filled in for all archs.
+ { "sh", "elf_sh", "sh", 2, EM_SH, 0, 0 },
+ { "arm", "ebl_arm", "arm", 3, EM_ARM, 0, 0 },
+ { "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 },
+ { "sparc", "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 },
+ { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 },
+ { "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
+
+ { "m32", "elf_m32", "m32", 3, EM_M32, 0, 0 },
+ { "m68k", "elf_m68k", "m68k", 4, EM_68K, 0, 0 },
+ { "m88k", "elf_m88k", "m88k", 4, EM_88K, 0, 0 },
+ { "i860", "elf_i860", "i860", 4, EM_860, 0, 0 },
+ { "s370", "ebl_s370", "s370", 4, EM_S370, 0, 0 },
+ { "parisc", "elf_parisc", "parisc", 6, EM_PARISC, 0, 0 },
+ { "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 },
+ { "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 },
+ { "i960", "elf_i960", "i960", 4, EM_960, 0, 0 },
+ { "v800", "ebl_v800", "v800", 4, EM_V800, 0, 0 },
+ { "fr20", "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 },
+ { "rh32", "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 },
+ { "rce", "ebl_rce", "rce", 3, EM_RCE, 0, 0 },
+ { "tricore", "elf_tricore", "tricore", 7, EM_TRICORE, 0, 0 },
+ { "arc", "elf_arc", "arc", 3, EM_ARC, 0, 0 },
+ { "h8", "elf_h8_300", "h8_300", 6, EM_H8_300, 0, 0 },
+ { "h8", "elf_h8_300h", "h8_300h", 6, EM_H8_300H, 0, 0 },
+ { "h8", "elf_h8s", "h8s", 6, EM_H8S, 0, 0 },
+ { "h8", "elf_h8_500", "h8_500", 6, EM_H8_500, 0, 0 },
+ { "coldfire", "elf_coldfire", "coldfire", 8, EM_COLDFIRE, 0, 0 },
+ { "m68k", "elf_68hc12", "68hc12", 6, EM_68HC12, 0, 0 },
+ { "mma", "elf_mma", "mma", 3, EM_MMA, 0, 0 },
+ { "pcp", "elf_pcp", "pcp", 3, EM_PCP, 0, 0 },
+ { "ncpu", "elf_ncpu", "ncpu", 4, EM_NCPU, 0, 0 },
+ { "ndr1", "elf_ndr1", "ndr1", 4, EM_NDR1, 0, 0 },
+ { "starcore", "elf_starcore", "starcore", 8, EM_STARCORE, 0, 0 },
+ { "me16", "elf_me16", "em16", 4, EM_ME16, 0, 0 },
+ { "st100", "elf_st100", "st100", 5, EM_ST100, 0, 0 },
+ { "tinyj", "elf_tinyj", "tinyj", 5, EM_TINYJ, 0, 0 },
+ { "pdsp", "elf_pdsp", "pdsp", 4, EM_PDSP, 0, 0 },
+ { "fx66", "elf_fx66", "fx66", 4, EM_FX66, 0, 0 },
+ { "st9plus", "elf_st9plus", "st9plus", 7, EM_ST9PLUS, 0, 0 },
+ { "st7", "elf_st7", "st7", 3, EM_ST7, 0, 0 },
+ { "m68k", "elf_68hc16", "68hc16", 6, EM_68HC16, 0, 0 },
+ { "m68k", "elf_68hc11", "68hc11", 6, EM_68HC11, 0, 0 },
+ { "m68k", "elf_68hc08", "68hc08", 6, EM_68HC08, 0, 0 },
+ { "m68k", "elf_68hc05", "68hc05", 6, EM_68HC05, 0, 0 },
+ { "svx", "elf_svx", "svx", 3, EM_SVX, 0, 0 },
+ { "st19", "elf_st19", "st19", 4, EM_ST19, 0, 0 },
+ { "vax", "elf_vax", "vax", 3, EM_VAX, 0, 0 },
+ { "cris", "elf_cris", "cris", 4, EM_CRIS, 0, 0 },
+ { "javelin", "elf_javelin", "javelin", 7, EM_JAVELIN, 0, 0 },
+ { "firepath", "elf_firepath", "firepath", 8, EM_FIREPATH, 0, 0 },
+ { "zsp", "elf_zsp", "zsp", 3, EM_ZSP, 0, 0 },
+ { "mmix", "elf_mmix", "mmix", 4, EM_MMIX, 0, 0 },
+ { "hunay", "elf_huany", "huany", 5, EM_HUANY, 0, 0 },
+ { "prism", "elf_prism", "prism", 5, EM_PRISM, 0, 0 },
+ { "avr", "elf_avr", "avr", 3, EM_AVR, 0, 0 },
+ { "fr30", "elf_fr30", "fr30", 4, EM_FR30, 0, 0 },
+ { "dv10", "elf_dv10", "dv10", 4, EM_D10V, 0, 0 },
+ { "dv30", "elf_dv30", "dv30", 4, EM_D30V, 0, 0 },
+ { "v850", "elf_v850", "v850", 4, EM_V850, 0, 0 },
+ { "m32r", "elf_m32r", "m32r", 4, EM_M32R, 0, 0 },
+ { "mn10300", "elf_mn10300", "mn10300", 7, EM_MN10300, 0, 0 },
+ { "mn10200", "elf_mn10200", "mn10200", 7, EM_MN10200, 0, 0 },
+ { "pj", "elf_pj", "pj", 2, EM_PJ, 0, 0 },
+ { "openrisc", "elf_openrisc", "openrisc", 8, EM_OPENRISC, 0, 0 },
+ { "arc", "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 },
+ { "xtensa", "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 },
+ { "aarch64", "elf_aarch64", "aarch64", 7, EM_AARCH64, ELFCLASS64, 0 },
+};
+#define nmachines (sizeof (machines) / sizeof (machines[0]))
+
+
+/* Default callbacks. Mostly they just return the error value. */
+static const char *default_object_type_name (int ignore, char *buf,
+ size_t len);
+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);
+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 GElf_Word default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2);
+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, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym,
+ const char *name,
+ const GElf_Shdr *destshdr);
+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 int default_syscall_abi (Ebl *ebl, int *sp, int *pc,
+ int *callno, int args[6]);
+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->object_type_name = default_object_type_name;
+ 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->sh_flags_combine = default_sh_flags_combine;
+ 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->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->syscall_abi = default_syscall_abi;
+ 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, emulation, machine)
+ 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];
+ }
+
+#ifndef LIBEBL_SUBDIR
+# define LIBEBL_SUBDIR PACKAGE
+#endif
+#define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
+
+ /* Give it a try. At least the machine type matches. First
+ try to load the module. */
+ char dsoname[100];
+ strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"),
+ machines[cnt].dsoname),
+ ".so");
+
+ void *h = dlopen (dsoname, RTLD_LAZY);
+ if (h == NULL)
+ {
+ strcpy (stpcpy (stpcpy (dsoname, "libebl_"),
+ machines[cnt].dsoname),
+ ".so");
+ h = dlopen (dsoname, RTLD_LAZY);
+ }
+
+ /* Try without an explicit path. */
+ if (h != NULL)
+ {
+ /* We managed to load the object. Now see whether the
+ initialization function likes our file. */
+ static const char version[] = MODVERSION;
+ const char *modversion;
+ ebl_bhinit_t initp;
+ char symname[machines[cnt].prefix_len + sizeof "_init"];
+
+ strcpy (mempcpy (symname, machines[cnt].prefix,
+ machines[cnt].prefix_len), "_init");
+
+ initp = (ebl_bhinit_t) dlsym (h, symname);
+ if (initp != NULL
+ && (modversion = initp (elf, machine, result, sizeof (Ebl)))
+ && strcmp (version, modversion) == 0)
+ {
+ /* We found a module to handle our file. */
+ result->dlhandle = h;
+ result->elf = elf;
+
+ /* A few entries are mandatory. */
+ assert (result->name != NULL);
+ assert (result->destr != NULL);
+
+ return result;
+ }
+
+ /* Not the module we need. */
+ (void) dlclose (h);
+ }
+
+ /* We cannot find a DSO but the emulation/machine ID matches.
+ Return that information. */
+ result->dlhandle = NULL;
+ result->elf = elf;
+ result->name = machines[cnt].prefix;
+ fill_defaults (result);
+
+ return result;
+ }
+
+ /* Nothing matched. We use only the default callbacks. */
+ result->dlhandle = NULL;
+ result->elf = elf;
+ result->emulation = "<unknown>";
+ result->name = "<unknown>";
+ fill_defaults (result);
+
+ return result;
+}
+
+
+/* Find an appropriate backend for the file associated with ELF. */
+Ebl *
+ebl_openbackend (elf)
+ 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 (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_object_type_name (int ignore __attribute__ ((unused)),
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ return NULL;
+}
+
+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)))
+{
+ 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 GElf_Word
+default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2)
+{
+ return SH_FLAGS_COMBINE (flags1, flags2);
+}
+
+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",
+ /* 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)
+ 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)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)),
+ const GElf_Sym *sym __attribute__ ((unused)),
+ const char *name __attribute__ ((unused)),
+ const GElf_Shdr *destshdr __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 int
+default_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+ int *sp, int *pc, int *callno, int args[6])
+{
+ *sp = *pc = *callno = -1;
+ args[0] = -1;
+ args[1] = -1;
+ args[2] = -1;
+ args[3] = -1;
+ args[4] = -1;
+ args[5] = -1;
+ return -1;
+}
+
+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/3rdparty/elfutils/libebl/eblosabiname.c b/3rdparty/elfutils/libebl/eblosabiname.c
new file mode 100644
index 0000000..3ea6f56
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblosabiname.c
@@ -0,0 +1,84 @@
+/* Return OS ABI name
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_osabi_name (ebl, osabi, buf, len)
+ 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 = gettext ("Stand alone");
+ else
+ {
+ snprintf (buf, len, "%s: %d", gettext ("<unknown>"), osabi);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblreginfo.c b/3rdparty/elfutils/libebl/eblreginfo.c
new file mode 100644
index 0000000..f213b4a
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblreginfo.c
@@ -0,0 +1,50 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+ssize_t
+ebl_register_info (ebl, regno, name, namelen, prefix, setname, bits, type)
+ 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/3rdparty/elfutils/libebl/eblrelativerelocp.c b/3rdparty/elfutils/libebl/eblrelativerelocp.c
new file mode 100644
index 0000000..297caec
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblrelativerelocp.c
@@ -0,0 +1,43 @@
+/* Check whether given relocation is a relative relocation.
+ Copyright (C) 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_relative_reloc_p (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl->relative_reloc_p (reloc);
+}
diff --git a/3rdparty/elfutils/libebl/eblrelocsimpletype.c b/3rdparty/elfutils/libebl/eblrelocsimpletype.c
new file mode 100644
index 0000000..085fc93
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblrelocsimpletype.c
@@ -0,0 +1,42 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+Elf_Type
+ebl_reloc_simple_type (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc) : ELF_T_NUM;
+}
diff --git a/3rdparty/elfutils/libebl/eblreloctypecheck.c b/3rdparty/elfutils/libebl/eblreloctypecheck.c
new file mode 100644
index 0000000..e322ace
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblreloctypecheck.c
@@ -0,0 +1,43 @@
+/* Check relocation type.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_reloc_type_check (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl != NULL ? ebl->reloc_type_check (reloc) : false;
+}
diff --git a/3rdparty/elfutils/libebl/eblreloctypename.c b/3rdparty/elfutils/libebl/eblreloctypename.c
new file mode 100644
index 0000000..fb39101
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblreloctypename.c
@@ -0,0 +1,53 @@
+/* Return relocation type name.
+ Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_reloc_type_name (ebl, reloc, buf, len)
+ 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 = "<INVALID RELOC>";
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblrelocvaliduse.c b/3rdparty/elfutils/libebl/eblrelocvaliduse.c
new file mode 100644
index 0000000..62c4ae7
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblrelocvaliduse.c
@@ -0,0 +1,43 @@
+/* Check relocation type use.
+ Copyright (C) 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_reloc_valid_use (ebl, reloc)
+ Ebl *ebl;
+ int reloc;
+{
+ return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, reloc) : false;
+}
diff --git a/3rdparty/elfutils/libebl/eblresolvesym.c b/3rdparty/elfutils/libebl/eblresolvesym.c
new file mode 100644
index 0000000..470f6f0
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+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/3rdparty/elfutils/libebl/eblretval.c b/3rdparty/elfutils/libebl/eblretval.c
new file mode 100644
index 0000000..056a549
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblretval.c
@@ -0,0 +1,44 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+int
+ebl_return_value_location (ebl, functypedie, locops)
+ Ebl *ebl;
+ Dwarf_Die *functypedie;
+ const Dwarf_Op **locops;
+{
+ return ebl == NULL ? -1 : ebl->return_value_location (functypedie, locops);
+}
diff --git a/3rdparty/elfutils/libebl/eblsectionname.c b/3rdparty/elfutils/libebl/eblsectionname.c
new file mode 100644
index 0000000..81c7add
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsectionname.c
@@ -0,0 +1,96 @@
+/* Return section name.
+ Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_section_name (ebl, section, xsection, buf, len, scnnames, shnum)
+ 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", gettext ("<unknown>"), section);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblsectionstripp.c b/3rdparty/elfutils/libebl/eblsectionstripp.c
new file mode 100644
index 0000000..c6cda63
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsectionstripp.c
@@ -0,0 +1,67 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libeblP.h"
+
+
+bool
+ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr, 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)
+ {
+ const char *s_l = elf_strptr (ebl->elf, ehdr->e_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/3rdparty/elfutils/libebl/eblsectiontypename.c b/3rdparty/elfutils/libebl/eblsectiontypename.c
new file mode 100644
index 0000000..3a30cd6
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsectiontypename.c
@@ -0,0 +1,127 @@
+/* Return section type name.
+ Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_section_type_name (ebl, section, buf, len)
+ 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", gettext ("<unknown>"), section);
+
+ res = buf;
+ break;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblsegmenttypename.c b/3rdparty/elfutils/libebl/eblsegmenttypename.c
new file mode 100644
index 0000000..3cad66e
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsegmenttypename.c
@@ -0,0 +1,90 @@
+/* Return segment type name.
+ Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_segment_type_name (ebl, segment, buf, len)
+ 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_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", gettext ("<unknown>"), segment);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblshflagscombine.c b/3rdparty/elfutils/libebl/eblshflagscombine.c
new file mode 100644
index 0000000..87625f8
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblshflagscombine.c
@@ -0,0 +1,44 @@
+/* Return combines section header flags value.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+GElf_Word
+ebl_sh_flags_combine (ebl, flags1, flags2)
+ Ebl *ebl;
+ GElf_Word flags1;
+ GElf_Word flags2;
+{
+ return ebl->sh_flags_combine (flags1, flags2);
+}
diff --git a/3rdparty/elfutils/libebl/eblstother.c b/3rdparty/elfutils/libebl/eblstother.c
new file mode 100644
index 0000000..ccbf138
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblstother.c
@@ -0,0 +1,43 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_check_st_other_bits (ebl, st_other)
+ 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/3rdparty/elfutils/libebl/eblstrtab.c b/3rdparty/elfutils/libebl/eblstrtab.c
new file mode 100644
index 0000000..798c34c
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblstrtab.c
@@ -0,0 +1,358 @@
+/* ELF string table handling.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include "libebl.h"
+#include <system.h>
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+struct Ebl_Strent
+{
+ const char *string;
+ size_t len;
+ struct Ebl_Strent *next;
+ struct Ebl_Strent *left;
+ struct Ebl_Strent *right;
+ size_t offset;
+ char reverse[0];
+};
+
+
+struct memoryblock
+{
+ struct memoryblock *next;
+ char memory[0];
+};
+
+
+struct Ebl_Strtab
+{
+ struct Ebl_Strent *root;
+ struct memoryblock *memory;
+ char *backp;
+ size_t left;
+ size_t total;
+ bool nullstr;
+
+ struct Ebl_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 *))
+
+
+struct Ebl_Strtab *
+ebl_strtabinit (bool nullstr)
+{
+ if (ps == 0)
+ {
+ ps = sysconf (_SC_PAGESIZE);
+ assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD);
+ }
+
+ struct Ebl_Strtab *ret
+ = (struct Ebl_Strtab *) calloc (1, sizeof (struct Ebl_Strtab));
+ if (ret != NULL)
+ {
+ ret->nullstr = nullstr;
+
+ if (nullstr)
+ {
+ ret->null.len = 1;
+ ret->null.string = "";
+ }
+ }
+
+ return ret;
+}
+
+
+static int
+morememory (struct Ebl_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
+ebl_strtabfree (struct Ebl_Strtab *st)
+{
+ struct memoryblock *mb = st->memory;
+
+ while (mb != NULL)
+ {
+ void *old = mb;
+ mb = mb->next;
+ free (old);
+ }
+
+ free (st);
+}
+
+
+static struct Ebl_Strent *
+newstring (struct Ebl_Strtab *st, const char *str, size_t len)
+{
+ /* Compute the amount of padding needed to make the structure aligned. */
+ size_t align = ((__alignof__ (struct Ebl_Strent)
+ - (((uintptr_t) st->backp)
+ & (__alignof__ (struct Ebl_Strent) - 1)))
+ & (__alignof__ (struct Ebl_Strent) - 1));
+
+ /* Make sure there is enough room in the memory block. */
+ if (st->left < align + sizeof (struct Ebl_Strent) + len)
+ {
+ if (morememory (st, sizeof (struct Ebl_Strent) + len))
+ return NULL;
+
+ align = 0;
+ }
+
+ /* Create the reserved string. */
+ struct Ebl_Strent *newstr = (struct Ebl_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 Ebl_Strent) + len;
+ st->left -= align + sizeof (struct Ebl_Strent) + len;
+
+ return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+ tree algorith (AVL, red-black trees). For now a simple, correct
+ implementation is enough. */
+static struct Ebl_Strent **
+searchstring (struct Ebl_Strent **sep, struct Ebl_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. */
+struct Ebl_Strent *
+ebl_strtabadd (struct Ebl_Strtab *st, const char *str, size_t len)
+{
+ /* Compute the string length if the caller doesn't know it. */
+ if (len == 0)
+ len = strlen (str) + 1;
+
+ /* 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. */
+ struct Ebl_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. */
+ struct Ebl_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 (struct Ebl_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;
+}
+
+
+static void
+copystrings (struct Ebl_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 (struct Ebl_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);
+}
+
+
+void
+ebl_strtabfinalize (struct Ebl_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)
+ abort ();
+
+ /* 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, &copylen);
+ assert (copylen == st->total + nulllen);
+}
+
+
+size_t
+ebl_strtaboffset (struct Ebl_Strent *se)
+{
+ return se->offset;
+}
+
+
+const char *
+ebl_string (struct Ebl_Strent *se)
+{
+ assert (se->string != NULL);
+
+ return se->string;
+}
diff --git a/3rdparty/elfutils/libebl/eblsymbolbindingname.c b/3rdparty/elfutils/libebl/eblsymbolbindingname.c
new file mode 100644
index 0000000..fd5bfda
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsymbolbindingname.c
@@ -0,0 +1,78 @@
+/* Return symbol binding name.
+ Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_symbol_binding_name (ebl, binding, buf, len)
+ 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
+ && (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, gettext ("<unknown>: %d"), binding);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblsymboltypename.c b/3rdparty/elfutils/libebl/eblsymboltypename.c
new file mode 100644
index 0000000..4e653d2
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsymboltypename.c
@@ -0,0 +1,84 @@
+/* Return symbol type name.
+ Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_symbol_type_name (ebl, symbol, buf, len)
+ 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
+ && (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, gettext ("<unknown>: %d"), symbol);
+
+ res = buf;
+ }
+ }
+
+ return res;
+}
diff --git a/3rdparty/elfutils/libebl/eblsysvhashentrysize.c b/3rdparty/elfutils/libebl/eblsysvhashentrysize.c
new file mode 100644
index 0000000..f966646
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblsysvhashentrysize.c
@@ -0,0 +1,42 @@
+/* Return OS ABI name
+ Copyright (C) 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_sysvhash_entrysize (ebl)
+ Ebl *ebl;
+{
+ return ebl->sysvhash_entrysize;
+}
diff --git a/3rdparty/elfutils/libebl/eblunwind.c b/3rdparty/elfutils/libebl/eblunwind.c
new file mode 100644
index 0000000..1251c1b
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblunwind.c
@@ -0,0 +1,43 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+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)
+{
+ if (ebl == NULL || ebl->unwind == NULL)
+ return false;
+ return ebl->unwind (ebl, pc, setfunc, getfunc, readfunc, arg, signal_framep);
+}
diff --git a/3rdparty/elfutils/libebl/eblwstrtab.c b/3rdparty/elfutils/libebl/eblwstrtab.c
new file mode 100644
index 0000000..08e0ba7
--- /dev/null
+++ b/3rdparty/elfutils/libebl/eblwstrtab.c
@@ -0,0 +1,359 @@
+/* ELF string table handling.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wchar.h>
+#include <sys/param.h>
+
+#include "libebl.h"
+#include <system.h>
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+struct Ebl_WStrent
+{
+ const wchar_t *string;
+ size_t len;
+ struct Ebl_WStrent *next;
+ struct Ebl_WStrent *left;
+ struct Ebl_WStrent *right;
+ size_t offset;
+ wchar_t reverse[0];
+};
+
+
+struct memoryblock
+{
+ struct memoryblock *next;
+ char memory[0];
+};
+
+
+struct Ebl_WStrtab
+{
+ struct Ebl_WStrent *root;
+ struct memoryblock *memory;
+ char *backp;
+ size_t left;
+ size_t total;
+ bool nullstr;
+
+ struct Ebl_WStrent null;
+};
+
+
+/* Cache for the pagesize. We correct this value a bit so that `malloc'
+ is not allocating more than a page. */
+static size_t ps;
+
+
+struct Ebl_WStrtab *
+ebl_wstrtabinit (bool nullstr)
+{
+ struct Ebl_WStrtab *ret;
+
+ if (ps == 0)
+ {
+ ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *);
+ assert (sizeof (struct memoryblock) < ps);
+ }
+
+ ret = (struct Ebl_WStrtab *) calloc (1, sizeof (struct Ebl_WStrtab));
+ if (ret != NULL)
+ {
+ ret->nullstr = nullstr;
+ if (nullstr)
+ {
+ ret->null.len = 1;
+ ret->null.string = L"";
+ }
+ }
+ return ret;
+}
+
+
+static int
+morememory (struct Ebl_WStrtab *st, size_t len)
+{
+ struct memoryblock *newmem;
+
+ if (len < ps)
+ len = ps;
+ newmem = (struct memoryblock *) malloc (len);
+ if (newmem == NULL)
+ return 1;
+
+ newmem->next = st->memory;
+ st->memory = newmem;
+ st->backp = newmem->memory;
+ st->left = len - offsetof (struct memoryblock, memory);
+
+ return 0;
+}
+
+
+void
+ebl_wstrtabfree (struct Ebl_WStrtab *st)
+{
+ struct memoryblock *mb = st->memory;
+
+ while (mb != NULL)
+ {
+ void *old = mb;
+ mb = mb->next;
+ free (old);
+ }
+
+ free (st);
+}
+
+
+static struct Ebl_WStrent *
+newstring (struct Ebl_WStrtab *st, const wchar_t *str, size_t len)
+{
+ struct Ebl_WStrent *newstr;
+ size_t align;
+ int i;
+
+ /* Compute the amount of padding needed to make the structure aligned. */
+ align = ((__alignof__ (struct Ebl_WStrent)
+ - (((uintptr_t) st->backp)
+ & (__alignof__ (struct Ebl_WStrent) - 1)))
+ & (__alignof__ (struct Ebl_WStrent) - 1));
+
+ /* Make sure there is enough room in the memory block. */
+ if (st->left < align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t))
+ {
+ if (morememory (st,
+ sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t)))
+ return NULL;
+
+ align = 0;
+ }
+
+ /* Create the reserved string. */
+ newstr = (struct Ebl_WStrent *) (st->backp + align);
+ newstr->string = str;
+ newstr->len = len;
+ newstr->next = NULL;
+ newstr->left = NULL;
+ newstr->right = NULL;
+ newstr->offset = 0;
+ for (i = len - 2; i >= 0; --i)
+ newstr->reverse[i] = str[len - 2 - i];
+ newstr->reverse[len - 1] = L'\0';
+ st->backp += align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t);
+ st->left -= align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t);
+
+ return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+ tree algorith (AVL, red-black trees). For now a simple, correct
+ implementation is enough. */
+static struct Ebl_WStrent **
+searchstring (struct Ebl_WStrent **sep, struct Ebl_WStrent *newstr)
+{
+ int cmpres;
+
+ /* More strings? */
+ if (*sep == NULL)
+ {
+ *sep = newstr;
+ return sep;
+ }
+
+ /* Compare the strings. */
+ cmpres = wmemcmp ((*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. */
+struct Ebl_WStrent *
+ebl_wstrtabadd (struct Ebl_WStrtab *st, const wchar_t *str, size_t len)
+{
+ struct Ebl_WStrent *newstr;
+ struct Ebl_WStrent **sep;
+
+ /* Compute the string length if the caller doesn't know it. */
+ if (len == 0)
+ len = wcslen (str) + 1;
+
+ /* 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. */
+ 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. */
+ 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)
+ {
+ struct Ebl_WStrent *subs;
+
+ /* Check whether we already know this string. */
+ for (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;
+}
+
+
+static void
+copystrings (struct Ebl_WStrent *nodep, wchar_t **freep, size_t *offsetp)
+{
+ struct Ebl_WStrent *subs;
+
+ if (nodep->left != NULL)
+ copystrings (nodep->left, freep, offsetp);
+
+ /* Process the current node. */
+ nodep->offset = *offsetp;
+ *freep = wmempcpy (*freep, nodep->string, nodep->len);
+ *offsetp += nodep->len * sizeof (wchar_t);
+
+ for (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);
+}
+
+
+void
+ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data)
+{
+ size_t copylen;
+ wchar_t *endp;
+ size_t nulllen = st->nullstr ? 1 : 0;
+
+ /* Fill in the information. */
+ data->d_buf = malloc ((st->total + nulllen) * sizeof (wchar_t));
+ if (data->d_buf == NULL)
+ abort ();
+
+ /* The first byte must always be zero if we created the table with a
+ null string. */
+ if (st->nullstr)
+ *((wchar_t *) data->d_buf) = L'\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. */
+ endp = (wchar_t *) data->d_buf + nulllen;
+ copylen = sizeof (wchar_t) * nulllen;
+ copystrings (st->root, &endp, &copylen);
+ assert (copylen == (st->total + nulllen) * sizeof (wchar_t));
+}
+
+
+size_t
+ebl_wstrtaboffset (struct Ebl_WStrent *se)
+{
+ return se->offset;
+}
diff --git a/3rdparty/elfutils/libebl/libebl.h b/3rdparty/elfutils/libebl/libebl.h
new file mode 100644
index 0000000..7c3c764
--- /dev/null
+++ b/3rdparty/elfutils/libebl/libebl.h
@@ -0,0 +1,466 @@
+/* Interface for libebl.
+ Copyright (C) 2000-2010, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBEBL_H
+#define _LIBEBL_H 1
+
+#include <gelf.h>
+#include "libdw.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "elf-knowledge.h"
+
+
+/* Opaque type for the handle. */
+typedef struct ebl Ebl;
+
+
+#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) __attribute__ ((__pure__));
+
+/* Get ELF class. */
+extern int ebl_get_elfclass (Ebl *ebl) __attribute__ ((__pure__));
+
+/* Get ELF data encoding. */
+extern int ebl_get_elfdata (Ebl *ebl) __attribute__ ((__pure__));
+
+
+/* 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_object_type_name (Ebl *ebl, int object,
+ char *buf, size_t len);
+
+/* 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. */
+extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc);
+
+/* 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, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym, const char *name,
+ const GElf_Shdr *destshdr);
+
+/* 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 combined section header flags value. */
+extern GElf_Word ebl_sh_flags_combine (Ebl *ebl, GElf_Word flags1,
+ GElf_Word flags2);
+
+/* 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, char *buf,
+ size_t len);
+
+/* Print information about object note if available. */
+extern void ebl_object_note (Ebl *ebl, 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_Ehdr *ehdr,
+ 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);
+
+/* Fill in the DWARF register numbers for the registers used in system calls.
+ The SP and PC are what kernel reports call the user stack pointer and PC.
+ The CALLNO and ARGS are the system call number and incoming arguments.
+ Each of these is filled with the DWARF register number corresponding,
+ or -1 if there is none. Returns zero when the information is available. */
+extern int ebl_syscall_abi (Ebl *ebl, int *sp, int *pc,
+ int *callno, int args[6]);
+
+/* 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);
+
+/* ELF string table handling. */
+struct Ebl_Strtab;
+struct Ebl_Strent;
+
+/* Create new ELF string table object in memory. */
+extern struct Ebl_Strtab *ebl_strtabinit (bool nullstr);
+
+/* Free resources allocated for ELF string table ST. */
+extern void ebl_strtabfree (struct Ebl_Strtab *st);
+
+/* Add string STR (length LEN is != 0) to ELF string table ST. */
+extern struct Ebl_Strent *ebl_strtabadd (struct Ebl_Strtab *st,
+ const char *str, size_t len);
+
+/* Finalize string table ST and store size and memory location information
+ in DATA. */
+extern void ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data);
+
+/* Get offset in string table for string associated with SE. */
+extern size_t ebl_strtaboffset (struct Ebl_Strent *se);
+
+/* Return the string associated with SE. */
+extern const char *ebl_string (struct Ebl_Strent *se);
+
+
+/* ELF wide char string table handling. */
+struct Ebl_WStrtab;
+struct Ebl_WStrent;
+
+/* Create new ELF wide char string table object in memory. */
+extern struct Ebl_WStrtab *ebl_wstrtabinit (bool nullstr);
+
+/* Free resources allocated for ELF wide char string table ST. */
+extern void ebl_wstrtabfree (struct Ebl_WStrtab *st);
+
+/* Add string STR (length LEN is != 0) to ELF string table ST. */
+extern struct Ebl_WStrent *ebl_wstrtabadd (struct Ebl_WStrtab *st,
+ const wchar_t *str, size_t len);
+
+/* Finalize string table ST and store size and memory location information
+ in DATA. */
+extern void ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data);
+
+/* Get offset in wide char string table for string associated with SE. */
+extern size_t ebl_wstrtaboffset (struct Ebl_WStrent *se);
+
+
+/* Generic string table handling. */
+struct Ebl_GStrtab;
+struct Ebl_GStrent;
+
+/* Create new string table object in memory. */
+extern struct Ebl_GStrtab *ebl_gstrtabinit (unsigned int width, bool nullstr);
+
+/* Free resources allocated for string table ST. */
+extern void ebl_gstrtabfree (struct Ebl_GStrtab *st);
+
+/* Add string STR (length LEN is != 0) to string table ST. */
+extern struct Ebl_GStrent *ebl_gstrtabadd (struct Ebl_GStrtab *st,
+ const char *str, size_t len);
+
+/* Finalize string table ST and store size and memory location information
+ in DATA. */
+extern void ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data);
+
+/* Get offset in wide char string table for string associated with SE. */
+extern size_t ebl_gstrtaboffset (struct Ebl_GStrent *se);
+
+
+/* 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,
+ 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);
+
+/* 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/3rdparty/elfutils/libebl/libebl.pro b/3rdparty/elfutils/libebl/libebl.pro
new file mode 100644
index 0000000..5e855c5
--- /dev/null
+++ b/3rdparty/elfutils/libebl/libebl.pro
@@ -0,0 +1,61 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../ebl
+
+include(../elfutils.pri)
+include(eblheaders.pri)
+
+SOURCES += \
+ $$PWD/ebl_check_special_section.c \
+ $$PWD/ebl_check_special_symbol.c \
+ $$PWD/ebl_syscall_abi.c \
+ $$PWD/eblabicfi.c \
+ $$PWD/eblauxvinfo.c \
+ $$PWD/eblbackendname.c \
+ $$PWD/eblbsspltp.c \
+ $$PWD/eblcheckobjattr.c \
+ $$PWD/eblcheckreloctargettype.c \
+ $$PWD/eblclosebackend.c \
+ $$PWD/eblcopyrelocp.c \
+ $$PWD/eblcorenote.c \
+ $$PWD/eblcorenotetypename.c \
+ $$PWD/ebldebugscnp.c \
+ $$PWD/ebldwarftoregno.c \
+ $$PWD/ebldynamictagcheck.c \
+ $$PWD/ebldynamictagname.c \
+ $$PWD/eblelfclass.c \
+ $$PWD/eblelfdata.c \
+ $$PWD/eblelfmachine.c \
+ $$PWD/eblgotpcreloccheck.c \
+ $$PWD/eblgstrtab.c \
+ $$PWD/eblinitreg.c \
+ $$PWD/eblmachineflagcheck.c \
+ $$PWD/eblmachineflagname.c \
+ $$PWD/eblmachinesectionflagcheck.c \
+ $$PWD/eblnonerelocp.c \
+ $$PWD/eblnormalizepc.c \
+ $$PWD/eblobjecttypename.c \
+ $$PWD/eblobjnote.c \
+ $$PWD/eblobjnotetypename.c \
+ $$PWD/eblopenbackend.c \
+ $$PWD/eblosabiname.c \
+ $$PWD/eblreginfo.c \
+ $$PWD/eblrelativerelocp.c \
+ $$PWD/eblrelocsimpletype.c \
+ $$PWD/eblreloctypecheck.c \
+ $$PWD/eblreloctypename.c \
+ $$PWD/eblrelocvaliduse.c \
+ $$PWD/eblresolvesym.c \
+ $$PWD/eblretval.c \
+ $$PWD/eblsectionname.c \
+ $$PWD/eblsectionstripp.c \
+ $$PWD/eblsectiontypename.c \
+ $$PWD/eblsegmenttypename.c \
+ $$PWD/eblshflagscombine.c \
+ $$PWD/eblstother.c \
+ $$PWD/eblstrtab.c \
+ $$PWD/eblsymbolbindingname.c \
+ $$PWD/eblsymboltypename.c \
+ $$PWD/eblsysvhashentrysize.c \
+ $$PWD/eblunwind.c \
+ $$PWD/eblwstrtab.c
diff --git a/3rdparty/elfutils/libebl/libeblP.h b/3rdparty/elfutils/libebl/libeblP.h
new file mode 100644
index 0000000..dbd67f3
--- /dev/null
+++ b/3rdparty/elfutils/libebl/libeblP.h
@@ -0,0 +1,97 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBEBLP_H
+#define _LIBEBLP_H 1
+
+#include <gelf.h>
+#include <libasm.h>
+#include <libebl.h>
+#include <libintl.h>
+
+
+/* Backend handle. */
+struct ebl
+{
+ /* Machine name. */
+ const char *name;
+
+ /* 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;
+
+ /* 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;
+
+ /* Internal data. */
+ void *dlhandle;
+};
+
+
+/* Type of the initialization functions in the backend modules. */
+typedef const char *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t);
+
+
+/* gettext helper macros. */
+#undef _
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* 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/3rdparty/elfutils/libelf/abstract.h b/3rdparty/elfutils/libelf/abstract.h
new file mode 100644
index 0000000..53713ee
--- /dev/null
+++ b/3rdparty/elfutils/libelf/abstract.h
@@ -0,0 +1,312 @@
+/* Abstract description of component ELF types.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+/* 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)
diff --git a/3rdparty/elfutils/libelf/common.h b/3rdparty/elfutils/libelf/common.h
new file mode 100644
index 0000000..744f1bb
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _COMMON_H
+#define _COMMON_H 1
+
+#include <ar.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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_NONE && version < EV_NUM)
+ 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, off_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 endianess 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/3rdparty/elfutils/libelf/dl-hash.h b/3rdparty/elfutils/libelf/dl-hash.h
new file mode 100644
index 0000000..e286d2e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/dl-hash.h
@@ -0,0 +1,82 @@
+/* Compute hash value for given string according to ELF standard.
+ Copyright (C) 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 1995.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#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 inline unsigned int
+__attribute__ ((__pure__))
+_dl_elf_hash (const char *name)
+{
+ const unsigned char *iname = (const unsigned char *) name;
+ unsigned int hash = (unsigned int) *iname++;
+ if (*iname != '\0')
+ {
+ hash = (hash << 4) + (unsigned int) *iname++;
+ if (*iname != '\0')
+ {
+ hash = (hash << 4) + (unsigned int) *iname++;
+ if (*iname != '\0')
+ {
+ hash = (hash << 4) + (unsigned int) *iname++;
+ if (*iname != '\0')
+ {
+ hash = (hash << 4) + (unsigned int) *iname++;
+ while (*iname != '\0')
+ {
+ unsigned int hi;
+ hash = (hash << 4) + (unsigned int) *iname++;
+ 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;
+ hash ^= hi >> 24;
+ }
+ }
+ }
+ }
+ }
+ return hash;
+}
+
+#endif /* dl-hash.h */
diff --git a/3rdparty/elfutils/libelf/elf-knowledge.h b/3rdparty/elfutils/libelf/elf-knowledge.h
new file mode 100644
index 0000000..24534b3
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf-knowledge.h
@@ -0,0 +1,104 @@
+/* Accumulation of various pieces of knowledge about ELF.
+ Copyright (C) 2000-2012, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _ELF_KNOWLEDGE_H
+#define _ELF_KNOWLEDGE_H 1
+
+#include <stdbool.h>
+
+
+/* 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)
+
+
+/* When combining ELF section flags we must distinguish two kinds:
+
+ - flags which cause problem if not added to the result even if not
+ present in all input sections
+
+ - flags which cause problem if added to the result if not present
+ in all input sections
+
+ The following definition is for the general case. There might be
+ machine specific extensions. */
+#define SH_FLAGS_COMBINE(Flags1, Flags2) \
+ (((Flags1 | Flags2) \
+ & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_LINK_ORDER \
+ | SHF_OS_NONCONFORMING | SHF_GROUP)) \
+ | (Flags1 & Flags2 & (SHF_MERGE | SHF_STRINGS | SHF_INFO_LINK)))
+
+/* Similar macro: return the bits of the flags which necessarily must
+ match if two sections are automatically combined. Sections still
+ can be forcefully combined in which case SH_FLAGS_COMBINE can be
+ used to determine the combined flags. */
+#define SH_FLAGS_IMPORTANT(Flags) \
+ ((Flags) & ~((GElf_Xword) 0 | SHF_LINK_ORDER | SHF_OS_NONCONFORMING))
+
+
+/* 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 what do these people do? They use 64-bit
+ entries. It is really shocking to see what kind of morons are out
+ there. And even worse: they are allowed to design ABIs. */
+#define SH_ENTSIZE_HASH(Ehdr) \
+ ((Ehdr)->e_machine == EM_ALPHA \
+ || ((Ehdr)->e_machine == EM_S390 \
+ && (Ehdr)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4)
+
+#endif /* elf-knowledge.h */
diff --git a/3rdparty/elfutils/libelf/elf.h b/3rdparty/elfutils/libelf/elf.h
new file mode 100644
index 0000000..40e87b2
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf.h
@@ -0,0 +1,3363 @@
+/* This file defines standard ELF types, structures, and macros.
+ Copyright (C) 1995-2014 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _ELF_H
+#define _ELF_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Standard ELF types. */
+
+#include <stdint.h>
+
+/* 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_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 */
+
+#define EM_PARISC 15 /* HPPA */
+#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_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_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 embedded processor */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
+#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 processor */
+#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_A5 93 /* ARC Cores Tangent-A5 */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_AARCH64 183 /* ARM AARCH64 */
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_NUM 192
+
+/* 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 indeces */
+#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_MASKOS 0x0ff00000 /* OS-specific. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
+#define SHF_ORDERED (1 << 30) /* Special ordering requirement
+ (Solaris). */
+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
+ referenced or allocated (Solaris).*/
+
+/* 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_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_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_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_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 */
+
+/* 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_NUM 34 /* 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. */
+
+/* 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. */
+
+/* Auxialiary 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 <elf.h> 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
+
+/* 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
+
+
+/* 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 */
+/* Keep this the last entry. */
+#define R_386_NUM 43
+
+/* 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_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
+
+/* 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
+
+/* 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
+#define DT_MIPS_NUM 0x35
+
+/* 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;
+
+
+/* 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 indeces. */
+
+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively 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 */
+
+/* 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_NUM 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 3
+
+/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */
+#define PPC64_OPT_TLS 1
+#define PPC64_OPT_MULTI_TOC 2
+
+/* 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. */
+#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_DTPMOD64 1028 /* Module number, 64 bit. */
+#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */
+#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */
+#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
+#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
+
+/* 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<cond>). */
+#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<cond>.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<cond>). */
+#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
+
+/* 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 */
+
+#define R_X86_64_NUM 39
+
+
+/* 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. */
+
+/* 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
+
+
+__END_DECLS
+
+#endif /* elf.h */
diff --git a/3rdparty/elfutils/libelf/elf32/elf32.pro b/3rdparty/elfutils/libelf/elf32/elf32.pro
new file mode 100644
index 0000000..3dcf8c0
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32/elf32.pro
@@ -0,0 +1,21 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../../elf32
+
+include(../../elfutils.pri)
+include(../elfheaders.pri)
+
+SOURCES += \
+ $$PWD/../elf32_checksum.c \
+ $$PWD/../elf32_fsize.c \
+ $$PWD/../elf32_getehdr.c \
+ $$PWD/../elf32_getphdr.c \
+ $$PWD/../elf32_getshdr.c \
+ $$PWD/../elf32_newehdr.c \
+ $$PWD/../elf32_newphdr.c \
+ $$PWD/../elf32_offscn.c \
+ $$PWD/../elf32_updatefile.c \
+ $$PWD/../elf32_updatenull.c \
+ $$PWD/../elf32_xlatetof.c \
+ $$PWD/../elf32_xlatetom.c \
+
diff --git a/3rdparty/elfutils/libelf/elf32_checksum.c b/3rdparty/elfutils/libelf/elf32_checksum.c
new file mode 100644
index 0000000..4c59856
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_checksum.c
@@ -0,0 +1,169 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+ Copyright (C) 2002, 2003, 2004, 2005, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#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 *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 endianess
+ 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/3rdparty/elfutils/libelf/elf32_fsize.c b/3rdparty/elfutils/libelf/elf32_fsize.c
new file mode 100644
index 0000000..d7496fa
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_fsize.c
@@ -0,0 +1,71 @@
+/* Return the size of an object file type.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+size_t
+elfw2(LIBELFBITS, fsize) (type, count, version)
+ 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_NONE) || unlikely (version >= EV_NUM))
+ {
+ __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+ return 0;
+ }
+
+ if (unlikely (type >= ELF_T_NUM))
+ {
+ __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+ return 0;
+ }
+
+#if EV_NUM != 2
+ return (count
+ * __libelf_type_sizes[version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+#else
+ return (count
+ * __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+#endif
+}
+#define local_strong_alias(n1, n2) strong_alias (n1, n2)
+local_strong_alias (elfw2(LIBELFBITS, fsize), __elfw2(LIBELFBITS, msize))
diff --git a/3rdparty/elfutils/libelf/elf32_getehdr.c b/3rdparty/elfutils/libelf/elf32_getehdr.c
new file mode 100644
index 0000000..ee0a2e0
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_getehdr.c
@@ -0,0 +1,99 @@
+/* Get ELF header.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static ElfW2(LIBELFBITS,Ehdr) *
+getehdr_impl (elf, wrlock)
+ 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) *
+__elfw2(LIBELFBITS,getehdr_wrlock) (elf)
+ Elf *elf;
+{
+ return getehdr_impl (elf, 1);
+}
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,getehdr) (elf)
+ 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/3rdparty/elfutils/libelf/elf32_getphdr.c b/3rdparty/elfutils/libelf/elf32_getphdr.c
new file mode 100644
index 0000000..1b82a48
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_getphdr.c
@@ -0,0 +1,257 @@
+/* Get ELF program header table.
+ Copyright (C) 1998-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+ElfW2(LIBELFBITS,Phdr) *
+__elfw2(LIBELFBITS,getphdr_wrlock) (elf)
+ 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
+ {
+ if (ALLOW_UNALIGNED
+ || ((uintptr_t) file_phdr
+ & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)
+ notcvt = file_phdr;
+ else
+ {
+ notcvt = (ElfW2(LIBELFBITS,Phdr) *) alloca (size);
+ 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);
+ }
+ }
+ }
+ }
+ 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 *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/3rdparty/elfutils/libelf/elf32_getshdr.c b/3rdparty/elfutils/libelf/elf32_getshdr.c
new file mode 100644
index 0000000..7417047
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_getshdr.c
@@ -0,0 +1,287 @@
+/* Return section header.
+ Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <system.h>
+#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
+ || (! 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) || ! ALLOW_UNALIGNED);
+ memcpy (shdr, file_shdr, size);
+ }
+ else
+ {
+ if (ALLOW_UNALIGNED
+ || ((uintptr_t) file_shdr
+ & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0)
+ notcvt = (ElfW2(LIBELFBITS,Shdr) *)
+ ((char *) elf->map_address
+ + elf->start_offset + ehdr->e_shoff);
+ else
+ {
+ notcvt = (ElfW2(LIBELFBITS,Shdr) *) alloca (size);
+ 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;
+ }
+ }
+ }
+ 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) *
+__elfw2(LIBELFBITS,getshdr_rdlock) (scn)
+ 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) *
+__elfw2(LIBELFBITS,getshdr_wrlock) (scn)
+ 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) (scn)
+ 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/3rdparty/elfutils/libelf/elf32_newehdr.c b/3rdparty/elfutils/libelf/elf32_newehdr.c
new file mode 100644
index 0000000..4b547bc
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_newehdr.c
@@ -0,0 +1,92 @@
+/* Create new ELF header.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,newehdr) (elf)
+ 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/3rdparty/elfutils/libelf/elf32_newphdr.c b/3rdparty/elfutils/libelf/elf32_newphdr.c
new file mode 100644
index 0000000..01038e7
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_newphdr.c
@@ -0,0 +1,182 @@
+/* Create new ELF program header table.
+ Copyright (C) 1999-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Phdr) *
+elfw2(LIBELFBITS,newphdr) (elf, count)
+ 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;
+ }
+
+ 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))))
+ {
+ 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. */
+ Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+ 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/3rdparty/elfutils/libelf/elf32_offscn.c b/3rdparty/elfutils/libelf/elf32_offscn.c
new file mode 100644
index 0000000..a1ff6d4
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_offscn.c
@@ -0,0 +1,101 @@
+/* Get section at specific index.
+ Copyright (C) 2005, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+Elf_Scn *
+elfw2(LIBELFBITS,offscn) (elf, offset)
+ 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/3rdparty/elfutils/libelf/elf32_updatefile.c b/3rdparty/elfutils/libelf/elf32_updatefile.c
new file mode 100644
index 0000000..153e377
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_updatefile.c
@@ -0,0 +1,808 @@
+/* Write changed data structures.
+ Copyright (C) 2000-2010, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+
+#include <system.h>
+#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);
+}
+
+
+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. */
+#if EV_NUM != 2
+ xfct_t fctp;
+ fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
+#endif
+
+ /* 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. */
+#if EV_NUM != 2
+ xfct_t fctp;
+ fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
+#endif
+
+ /* 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
+ memcpy (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 **) alloca (shnum * sizeof (Elf_Scn *));
+ char *const shdr_start = ((char *) elf->map_address + elf->start_offset
+ + ehdr->e_shoff);
+ char *const shdr_end = shdr_start + ehdr->e_shnum * ehdr->e_shentsize;
+
+#if EV_NUM != 2
+ xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+#else
+# undef shdr_fctp
+# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
+#endif
+#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 = alloca (sizeof (ElfW2(LIBELFBITS,Shdr)));
+ 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 (p == NULL)
+ {
+ __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;
+
+ void fill_mmap (size_t offset)
+ {
+ 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);
+ }
+ }
+
+ 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 + 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. */
+
+ last_position = scn_start + dl->data.d.d_off;
+
+ if (unlikely (change_bo))
+ {
+#if EV_NUM != 2
+ xfct_t fctp;
+ fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
+#endif
+
+ /* Do the real work. */
+ (*fctp) (last_position, dl->data.d.d_buf,
+ dl->data.d.d_size, 1);
+
+ last_position += dl->data.d.d_size;
+ }
+ else
+ last_position = mempcpy (last_position,
+ dl->data.d.d_buf,
+ 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);
+
+ /* 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];
+
+ scn->shdr_flags &= ~ELF_F_DIRTY;
+ }
+ }
+ }
+
+ /* 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, off_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. */
+#if EV_NUM != 2
+ xfct_t fctp;
+ fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
+#endif
+
+ /* 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. */
+#if EV_NUM != 2
+ xfct_t fctp;
+ fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
+#endif
+
+ /* Allocate sufficient memory. */
+ tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *)
+ malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
+ if (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. */
+ off_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;
+
+ off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
+#if EV_NUM != 2
+ xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+#else
+# undef shdr_fctp
+# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
+#endif
+
+ ElfW2(LIBELFBITS,Shdr) *shdr_data;
+ if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+ || (elf->flags & ELF_F_DIRTY))
+ shdr_data = (ElfW2(LIBELFBITS,Shdr) *)
+ alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
+ 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 **) alloca (shnum * sizeof (Elf_Scn *));
+ 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;
+
+ off_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))
+ return 1;
+ }
+
+ 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. */
+
+ last_offset = scn_start + dl->data.d.d_off;
+
+ if (unlikely (change_bo))
+ {
+#if EV_NUM != 2
+ xfct_t fctp;
+ fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
+#endif
+
+ buf = tmpbuf;
+ if (dl->data.d.d_size > MAX_TMPBUF)
+ {
+ buf = malloc (dl->data.d.d_size);
+ if (buf == NULL)
+ {
+ __libelf_seterrno (ELF_E_NOMEM);
+ return 1;
+ }
+ }
+
+ /* 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);
+ return 1;
+ }
+
+ 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))
+ return 1;
+ }
+
+ 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))
+ return 1;
+
+ /* 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);
+ return 1;
+ }
+ }
+
+ /* That was the last part. Clear the overall flag. */
+ elf->flags &= ~ELF_F_DIRTY;
+
+ return 0;
+}
diff --git a/3rdparty/elfutils/libelf/elf32_updatenull.c b/3rdparty/elfutils/libelf/elf32_updatenull.c
new file mode 100644
index 0000000..be4cea0
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_updatenull.c
@@ -0,0 +1,417 @@
+/* Update data structures for changes.
+ Copyright (C) 2000-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include "libelfP.h"
+#include "elf-knowledge.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+
+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)
+ || unlikely (ehdr->e_version >= EV_NUM))
+ {
+ __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;
+ }
+
+ return 0;
+}
+
+
+off_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. */
+ off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+
+ /* Set the program header position. */
+ if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL
+ && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
+ || ehdr->e_type == ET_CORE))
+ (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
+ if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
+ {
+ /* Only executables, shared objects, and core files have a program
+ header. */
+ if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
+ && unlikely (ehdr->e_type != ET_CORE))
+ {
+ __libelf_seterrno (ELF_E_INVALID_PHDR);
+ return -1;
+ }
+
+ 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_t) 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)
+ {
+ 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;
+
+ /* Load the section headers if necessary. This loads the
+ headers for all sections. */
+ if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL)
+ (void) __elfw2(LIBELFBITS,getshdr_wrlock) (&list->data[1]);
+
+ 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);
+ off_t offset = 0;
+
+ assert (shdr != NULL);
+ ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
+ ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 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);
+
+ 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_NONE)
+ || unlikely (data->d_version >= EV_NUM))
+ {
+ __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 ((GElf_Word) (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 ((GElf_Word) size,
+ shdr->sh_offset
+ + (shdr->sh_type != SHT_NOBITS
+ ? 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 < 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, (GElf_Word) 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. */
+ update_if_changed (shdr->sh_size, (GElf_Word) offset,
+ changed);
+
+ if (shdr->sh_type != SHT_NOBITS)
+ size += offset;
+
+ scn->flags |= changed;
+ }
+
+ /* Check that the section size is actually a multiple of
+ the entry size. */
+ if (shdr->sh_entsize != 0
+ && unlikely (shdr->sh_size % shdr->sh_entsize != 0)
+ && (elf->flags & ELF_F_PERMISSIVE) == 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. */
+ 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 ((GElf_Word) 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, (GElf_Word) size, elf->flags);
+ update_if_changed (ehdr->e_shentsize,
+ elf_typesize (LIBELFBITS, ELF_T_SHDR, 1),
+ ehdr_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/3rdparty/elfutils/libelf/elf32_xlatetof.c b/3rdparty/elfutils/libelf/elf32_xlatetof.c
new file mode 100644
index 0000000..27a973e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_xlatetof.c
@@ -0,0 +1,123 @@
+/* Convert from memory to file representation.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+Elf_Data *
+elfw2(LIBELFBITS, xlatetof) (dest, src, encode)
+ 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. */
+#if EV_NUM != 2
+ size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#else
+ size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#endif
+
+ 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;
+
+ /* Get a pointer to the transformation functions. The `#ifdef' is
+ a small optimization since we don't anticipate another ELF
+ version and so would waste "precious" code. */
+#if EV_NUM != 2
+ fctp = __elf_xfctstom[dest->d_version - 1][src->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#else
+ fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#endif
+
+ /* 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/3rdparty/elfutils/libelf/elf32_xlatetom.c b/3rdparty/elfutils/libelf/elf32_xlatetom.c
new file mode 100644
index 0000000..368df07
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf32_xlatetom.c
@@ -0,0 +1,128 @@
+/* Convert from file to memory representation.
+ Copyright (C) 1998, 1999, 2000, 2002, 2012 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+Elf_Data *
+elfw2(LIBELFBITS, xlatetom) (dest, src, encode)
+ 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. */
+#if EV_NUM != 2
+ size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#else
+ size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#endif
+
+
+ /* 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_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;
+
+ /* Get a pointer to the transformation functions. The `#ifdef' is
+ a small optimization since we don't anticipate another ELF
+ version and so would waste "precious" code. */
+#if EV_NUM != 2
+ fctp = __elf_xfctstom[src->d_version - 1][dest->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#else
+ fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#endif
+
+ /* 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/3rdparty/elfutils/libelf/elf64/elf64.pro b/3rdparty/elfutils/libelf/elf64/elf64.pro
new file mode 100644
index 0000000..021b53e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf64/elf64.pro
@@ -0,0 +1,20 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../../elf64
+
+include(../../elfutils.pri)
+include(../elfheaders.pri)
+
+SOURCES += \
+ $$PWD/../elf64_checksum.c \
+ $$PWD/../elf64_fsize.c \
+ $$PWD/../elf64_getehdr.c \
+ $$PWD/../elf64_getphdr.c \
+ $$PWD/../elf64_getshdr.c \
+ $$PWD/../elf64_newehdr.c \
+ $$PWD/../elf64_newphdr.c \
+ $$PWD/../elf64_offscn.c \
+ $$PWD/../elf64_updatefile.c \
+ $$PWD/../elf64_updatenull.c \
+ $$PWD/../elf64_xlatetof.c \
+ $$PWD/../elf64_xlatetom.c \
diff --git a/3rdparty/elfutils/libelf/elf64_checksum.c b/3rdparty/elfutils/libelf/elf64_checksum.c
new file mode 100644
index 0000000..1802240
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_checksum.c"
diff --git a/3rdparty/elfutils/libelf/elf64_fsize.c b/3rdparty/elfutils/libelf/elf64_fsize.c
new file mode 100644
index 0000000..1ee1067
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_fsize.c"
diff --git a/3rdparty/elfutils/libelf/elf64_getehdr.c b/3rdparty/elfutils/libelf/elf64_getehdr.c
new file mode 100644
index 0000000..b35e7f6
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_getehdr.c"
diff --git a/3rdparty/elfutils/libelf/elf64_getphdr.c b/3rdparty/elfutils/libelf/elf64_getphdr.c
new file mode 100644
index 0000000..c1ee60f
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_getphdr.c"
diff --git a/3rdparty/elfutils/libelf/elf64_getshdr.c b/3rdparty/elfutils/libelf/elf64_getshdr.c
new file mode 100644
index 0000000..c50cc71
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_getshdr.c"
diff --git a/3rdparty/elfutils/libelf/elf64_newehdr.c b/3rdparty/elfutils/libelf/elf64_newehdr.c
new file mode 100644
index 0000000..65dd0f7
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_newehdr.c"
diff --git a/3rdparty/elfutils/libelf/elf64_newphdr.c b/3rdparty/elfutils/libelf/elf64_newphdr.c
new file mode 100644
index 0000000..58bfc73
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_newphdr.c"
diff --git a/3rdparty/elfutils/libelf/elf64_offscn.c b/3rdparty/elfutils/libelf/elf64_offscn.c
new file mode 100644
index 0000000..1b37b36
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_offscn.c"
diff --git a/3rdparty/elfutils/libelf/elf64_updatefile.c b/3rdparty/elfutils/libelf/elf64_updatefile.c
new file mode 100644
index 0000000..6941fe9
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_updatefile.c"
diff --git a/3rdparty/elfutils/libelf/elf64_updatenull.c b/3rdparty/elfutils/libelf/elf64_updatenull.c
new file mode 100644
index 0000000..8333b5b
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_updatenull.c"
diff --git a/3rdparty/elfutils/libelf/elf64_xlatetof.c b/3rdparty/elfutils/libelf/elf64_xlatetof.c
new file mode 100644
index 0000000..aacf5b0
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_xlatetof.c"
diff --git a/3rdparty/elfutils/libelf/elf64_xlatetom.c b/3rdparty/elfutils/libelf/elf64_xlatetom.c
new file mode 100644
index 0000000..034262c
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#define LIBELFBITS 64
+#include "elf32_xlatetom.c"
diff --git a/3rdparty/elfutils/libelf/elf_begin.c b/3rdparty/elfutils/libelf/elf_begin.c
new file mode 100644
index 0000000..30abe0b
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_begin.c
@@ -0,0 +1,1135 @@
+/* Create descriptor for processing file.
+ Copyright (C) 1998-2010, 2012, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <system.h>
+#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, off_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;
+
+ /* 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 + offset))
+ & (__alignof__ (Elf32_Ehdr) - 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;
+
+ 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 (pread_retry (fildes, &size, sizeof (Elf32_Word),
+ offset + ehdr.e32->e_shoff
+ + offsetof (Elf32_Shdr, sh_size))
+ != sizeof (Elf32_Word)))
+ 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 + offset))
+ & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
+ /* We can directly access the memory. */
+ size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
+ + offset))->sh_size;
+ else
+ {
+ 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 (pread_retry (fildes, &size, sizeof (Elf64_Word),
+ offset + ehdr.e64->e_shoff
+ + offsetof (Elf64_Shdr, sh_size))
+ != sizeof (Elf64_Xword)))
+ return (size_t) -1l;
+
+ if (e_ident[EI_DATA] != MY_ELFDATA)
+ CONVERT (size);
+ }
+
+ if (size > ~((GElf_Word) 0))
+ /* Invalid value, it is too large. */
+ 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,
+ off_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_FILE);
+ return NULL;
+ }
+
+ /* Determine the number of sections. */
+ 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)))
+ return NULL;
+ }
+ else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
+ 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. */
+ 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
+ && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff)
+ & (__alignof__ (Elf32_Shdr) - 1)) == 0
+ && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff)
+ & (__alignof__ (Elf32_Phdr) - 1)) == 0)))
+ {
+ /* We can use the mmapped memory. */
+ elf->state.elf32.ehdr = ehdr;
+
+ if (unlikely (ehdr->e_shoff >= maxsize)
+ || unlikely (maxsize - ehdr->e_shoff
+ < scncnt * sizeof (Elf32_Shdr)))
+ {
+ free_and_out:
+ free (elf);
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ return NULL;
+ }
+ elf->state.elf32.shdr
+ = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff);
+
+ /* Don't precache the phdr pointer here.
+ elf32_getphdr will validate it against the size when asked. */
+
+ 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
+ {
+ /* 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);
+ }
+
+ 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
+ && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff)
+ & (__alignof__ (Elf64_Shdr) - 1)) == 0
+ && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff)
+ & (__alignof__ (Elf64_Phdr) - 1)) == 0)))
+ {
+ /* We can use the mmapped memory. */
+ elf->state.elf64.ehdr = ehdr;
+
+ if (unlikely (ehdr->e_shoff >= maxsize)
+ || unlikely (maxsize - ehdr->e_shoff
+ < scncnt * sizeof (Elf64_Shdr)))
+ goto free_and_out;
+ elf->state.elf64.shdr
+ = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff);
+
+ /* Don't precache the phdr pointer here.
+ elf64_getphdr will validate it against the size when asked. */
+
+ 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
+ {
+ /* 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);
+ }
+
+ 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, off_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, off_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, off_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 (use_mmap)
+ {
+ 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;
+ }
+
+ /* 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
+ {
+ /* The parent is already loaded. Use it. */
+ assert (maxsize != ~((size_t) 0));
+
+ 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;
+ }
+
+ len = atol (hdr->ar_size);
+
+ if (memcmp (hdr->ar_name, "// ", 16) == 0)
+ break;
+
+ offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
+ }
+
+ /* 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)
+ {
+ if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
+ goto too_much;
+ /* 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))
+ {
+ too_much:
+ /* 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';
+
+ /* Skip the NUL byte and the \012. */
+ runp += 2;
+
+ /* 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 *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);
+
+ /* Truncated file? */
+ size_t maxsize;
+ maxsize = 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 desriptor 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 desriptor 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;
+}
+
+
+/* Return a descriptor for the file belonging to FILDES. */
+Elf *
+elf_begin (fildes, cmd, ref)
+ int fildes;
+ Elf_Cmd cmd;
+ Elf *ref;
+{
+ Elf *retval;
+
+ if (unlikely (! __libelf_version_initialized))
+ {
+ /* 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_GETFL) == -1 && errno == EBADF))
+ {
+ /* We cannot do anything productive without a file descriptor. */
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ return NULL;
+ }
+
+ Elf *lock_dup_elf ()
+ {
+ /* 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);
+ }
+
+ 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 ();
+ 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 ();
+ }
+ 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/3rdparty/elfutils/libelf/elf_clone.c b/3rdparty/elfutils/libelf/elf_clone.c
new file mode 100644
index 0000000..e6fe472
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#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/3rdparty/elfutils/libelf/elf_cntl.c b/3rdparty/elfutils/libelf/elf_cntl.c
new file mode 100644
index 0000000..a3c5805
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_cntl.c
@@ -0,0 +1,83 @@
+/* Control an ELF file desrciptor.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+int
+elf_cntl (elf, cmd)
+ 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/3rdparty/elfutils/libelf/elf_end.c b/3rdparty/elfutils/libelf/elf_end.c
new file mode 100644
index 0000000..d4ae051
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_end.c
@@ -0,0 +1,232 @@
+/* Free resources associated with Elf descriptor.
+ Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "libelfP.h"
+
+
+int
+elf_end (elf)
+ 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);
+
+ /* 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. */
+ if (elf->map_address == NULL)
+ 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/3rdparty/elfutils/libelf/elf_error.c b/3rdparty/elfutils/libelf/elf_error.c
new file mode 100644
index 0000000..aa7f917
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_error.c
@@ -0,0 +1,309 @@
+/* Error handling in libelf.
+ Copyright (C) 1998-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#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_OP_IDX \
+ (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor")
+ 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")
+};
+
+
+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_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
+};
+#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0])))
+
+
+void
+__libelf_seterrno (value)
+ int value;
+{
+ global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR;
+}
+
+
+const char *
+elf_errmsg (error)
+ 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/3rdparty/elfutils/libelf/elf_fill.c b/3rdparty/elfutils/libelf/elf_fill.c
new file mode 100644
index 0000000..174ab45
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_fill.c
@@ -0,0 +1,47 @@
+/* Set fill byte used when constructing ELF objects.
+ Copyright (C) 1998, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+
+#include "libelfP.h"
+
+
+int __libelf_fill_byte;
+
+
+void
+elf_fill (fill)
+ int fill;
+{
+ __libelf_fill_byte = fill;
+}
diff --git a/3rdparty/elfutils/libelf/elf_flagdata.c b/3rdparty/elfutils/libelf/elf_flagdata.c
new file mode 100644
index 0000000..ace8cc5
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_flagdata.c
@@ -0,0 +1,71 @@
+/* Manipulate ELF data flag.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagdata (data, cmd, flags)
+ 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/3rdparty/elfutils/libelf/elf_flagehdr.c b/3rdparty/elfutils/libelf/elf_flagehdr.c
new file mode 100644
index 0000000..d3a320b
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_flagehdr.c
@@ -0,0 +1,68 @@
+/* Manipulate ELF header flags.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagehdr (elf, cmd, flags)
+ 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/3rdparty/elfutils/libelf/elf_flagelf.c b/3rdparty/elfutils/libelf/elf_flagelf.c
new file mode 100644
index 0000000..b34bd4f
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_flagelf.c
@@ -0,0 +1,70 @@
+/* Manipulate ELF file flags.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagelf (elf, cmd, flags)
+ 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/3rdparty/elfutils/libelf/elf_flagphdr.c b/3rdparty/elfutils/libelf/elf_flagphdr.c
new file mode 100644
index 0000000..2a589cc
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_flagphdr.c
@@ -0,0 +1,68 @@
+/* Manipulate ELF program header flags.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagphdr (elf, cmd, flags)
+ 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/3rdparty/elfutils/libelf/elf_flagscn.c b/3rdparty/elfutils/libelf/elf_flagscn.c
new file mode 100644
index 0000000..3ff826c
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_flagscn.c
@@ -0,0 +1,68 @@
+/* Manipulate ELF section flags.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagscn (scn, cmd, flags)
+ 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/3rdparty/elfutils/libelf/elf_flagshdr.c b/3rdparty/elfutils/libelf/elf_flagshdr.c
new file mode 100644
index 0000000..8d797af
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_flagshdr.c
@@ -0,0 +1,68 @@
+/* Manipulate ELF section header flags.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagshdr (scn, cmd, flags)
+ 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/3rdparty/elfutils/libelf/elf_getarhdr.c b/3rdparty/elfutils/libelf/elf_getarhdr.c
new file mode 100644
index 0000000..f8b36b8
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getarhdr.c
@@ -0,0 +1,74 @@
+/* Read header of next archive member.
+ Copyright (C) 1998, 1999, 2000, 2002, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Arhdr *
+elf_getarhdr (elf)
+ 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/3rdparty/elfutils/libelf/elf_getaroff.c b/3rdparty/elfutils/libelf/elf_getaroff.c
new file mode 100644
index 0000000..62da34d
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getaroff.c
@@ -0,0 +1,54 @@
+/* Return offset in archive for current file ELF.
+ Copyright (C) 2005, 2008 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getaroff (elf)
+ 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/3rdparty/elfutils/libelf/elf_getarsym.c b/3rdparty/elfutils/libelf/elf_getarsym.c
new file mode 100644
index 0000000..40633aa
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getarsym.c
@@ -0,0 +1,309 @@
+/* Return symbol table of archive.
+ Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include <dl-hash.h>
+#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, ptr)
+ 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;
+
+ 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;
+ 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)
+ {
+ union
+ {
+ uint32_t u32[n];
+ uint64_t u64[n];
+ } *file_data;
+ char *str_data;
+ size_t sz = n * w;
+
+ if (elf->map_address == NULL)
+ {
+ file_data = alloca (sz);
+
+ 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)
+ file_data = memcpy (alloca (sz), 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;
+ for (size_t cnt = 0; cnt < n; ++cnt)
+ {
+ arsym[cnt].as_name = str_data;
+ if (index64_p)
+ {
+ uint64_t tmp = file_data->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 (file_data->u32[cnt]);
+ else
+ arsym[cnt].as_off = file_data->u32[cnt];
+
+ arsym[cnt].as_hash = _dl_elf_hash (str_data);
+ str_data = rawmemchr (str_data, '\0') + 1;
+ }
+
+ /* 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:
+ rwlock_unlock (elf->lock);
+ }
+
+ if (ptr != NULL)
+ *ptr = elf->state.ar.ar_sym_num;
+
+ return result;
+}
diff --git a/3rdparty/elfutils/libelf/elf_getbase.c b/3rdparty/elfutils/libelf/elf_getbase.c
new file mode 100644
index 0000000..ff0feb4
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getbase.c
@@ -0,0 +1,45 @@
+/* Return offset of first byte for the object.
+ Copyright (C) 1998, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getbase (elf)
+ Elf *elf;
+{
+ return elf == NULL ? (off_t) -1 : elf->start_offset;
+}
diff --git a/3rdparty/elfutils/libelf/elf_getdata.c b/3rdparty/elfutils/libelf/elf_getdata.c
new file mode 100644
index 0000000..0aeb997
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getdata.c
@@ -0,0 +1,487 @@
+/* Return the next data element from the section after possibly converting it.
+ Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include <system.h>
+#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[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
+ {
+ [EV_CURRENT - 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,
+ [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,
+ }
+ };
+
+#if !ALLOW_UNALIGNED
+/* Associate libelf types with their internal alignment requirements. */
+const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+ {
+# define TYPE_ALIGNS(Bits) \
+ { \
+ [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)), \
+ [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)), \
+ [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \
+ [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)), \
+ }
+ [EV_CURRENT - 1] =
+ {
+ [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
+ [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
+ }
+# undef TYPE_ALIGNS
+ };
+#endif
+
+
+/* Convert the data in the current section. */
+static void
+convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
+ int data, size_t size, Elf_Type type)
+{
+ const size_t align = __libelf_type_align (eclass, type);
+
+ if (data == MY_ELFDATA)
+ {
+ 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;
+ }
+
+ /* Get the conversion function. */
+#if EV_NUM != 2
+ fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
+#else
+ fp = __elf_xfctstom[0][0][eclass - 1][type];
+#endif
+
+ fp (scn->data_base, scn->rawdata_base, size, 0);
+ }
+
+ 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;
+ 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;
+ }
+ 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;
+ }
+
+ /* 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;
+
+ if (type == SHT_HASH)
+ {
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+ entsize = SH_ENTSIZE_HASH (ehdr);
+ }
+ else
+ {
+ Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
+ if (t == ELF_T_VDEF || t == ELF_T_NHDR
+ || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
+ entsize = 1;
+ else
+ entsize = __libelf_type_sizes[LIBELF_EV_IDX][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))
+ {
+ /* 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;
+ /* Some broken ELF ABI for 64-bit machines use the wrong hash table
+ entry size. See elf-knowledge.h for more information. */
+ if (type == SHT_HASH && elf->class == ELFCLASS64)
+ {
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+ scn->rawdata.d.d_type
+ = (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
+ }
+ else
+ scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
+ scn->rawdata.d.d_off = 0;
+ 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;
+}
+
+Elf_Data *
+internal_function
+__elf_getdata_rdlock (scn, data)
+ 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)
+ {
+ if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
+ {
+ if (!locked)
+ {
+ rwlock_unlock (elf->lock);
+ rwlock_wrlock (elf->lock);
+ if (scn->data_list_rear != NULL)
+ goto pass;
+ }
+
+ /* Convert according to the version and the type. */
+ convert_data (scn, __libelf_version, 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;
+ }
+
+ /* If no data is present we cannot return any. */
+ if (scn->data_list_rear != NULL)
+ pass:
+ /* Return the first data element in the list. */
+ result = &scn->data_list.data.d;
+
+ out:
+ return result;
+}
+
+Elf_Data *
+elf_getdata (scn, data)
+ 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/3rdparty/elfutils/libelf/elf_getdata_rawchunk.c b/3rdparty/elfutils/libelf/elf_getdata_rawchunk.c
new file mode 100644
index 0000000..63a9914
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getdata_rawchunk.c
@@ -0,0 +1,177 @@
+/* Return converted data from raw chunk of ELF file.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+Elf_Data *
+elf_getdata_rawchunk (elf, offset, size, type)
+ Elf *elf;
+ off64_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);
+
+ /* If the file is mmap'ed we can use it directly. */
+ if (elf->map_address != NULL)
+ rawchunk = elf->map_address + elf->start_offset + offset;
+ 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. */
+ size_t align = __libelf_type_align (elf->class, type);
+ 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[LIBELF_EV_IDX][LIBELF_EV_IDX][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 = __libelf_version;
+
+ 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/3rdparty/elfutils/libelf/elf_getident.c b/3rdparty/elfutils/libelf/elf_getident.c
new file mode 100644
index 0000000..10beeaf
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getident.c
@@ -0,0 +1,63 @@
+/* Retrieve file identification data.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_getident (elf, ptr)
+ 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/3rdparty/elfutils/libelf/elf_getphdrnum.c b/3rdparty/elfutils/libelf/elf_getphdrnum.c
new file mode 100644
index 0000000..63c27fb
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getphdrnum.c
@@ -0,0 +1,136 @@
+/* Return number of program headers in the ELF file.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+__elf_getphdrnum_rdlock (elf, dst)
+ Elf *elf;
+ size_t *dst;
+{
+ if (unlikely (elf->state.elf64.ehdr == NULL))
+ {
+ /* Maybe no ELF header was created yet. */
+ __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->state.elf32.scns.data[0].shdr.e32 != NULL))
+ *dst = scns->data[0].shdr.e32->sh_info;
+ }
+ else
+ {
+ if (likely (scns->cnt > 0
+ && elf->state.elf64.scns.data[0].shdr.e64 != NULL))
+ *dst = scns->data[0].shdr.e64->sh_info;
+ }
+ }
+
+ return 0;
+}
+
+int
+elf_getphdrnum (elf, dst)
+ 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_rdlock (elf, dst);
+
+ /* Do some sanity checking to make sure phnum and phoff are consistent. */
+ Elf64_Off off = (elf->class == ELFCLASS32
+ ? elf->state.elf32.ehdr->e_phoff
+ : elf->state.elf64.ehdr->e_phoff);
+ if (unlikely (off == 0))
+ {
+ *dst = 0;
+ goto out;
+ }
+
+ if (unlikely (off >= elf->maximum_size))
+ {
+ __libelf_seterrno (ELF_E_INVALID_DATA);
+ result = -1;
+ goto out;
+ }
+
+ /* 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);
+ result = -1;
+ goto out;
+ }
+
+ /* 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;
+
+out:
+ rwlock_unlock (elf->lock);
+
+ return result;
+}
diff --git a/3rdparty/elfutils/libelf/elf_getscn.c b/3rdparty/elfutils/libelf/elf_getscn.c
new file mode 100644
index 0000000..7c6b7de
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getscn.c
@@ -0,0 +1,89 @@
+/* Get section at specific index.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_getscn (elf, idx)
+ 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);
+ 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;
+ }
+ }
+
+ rwlock_unlock (elf->lock);
+
+ return result;
+}
+INTDEF(elf_getscn)
diff --git a/3rdparty/elfutils/libelf/elf_getshdrnum.c b/3rdparty/elfutils/libelf/elf_getshdrnum.c
new file mode 100644
index 0000000..73a3300
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getshdrnum.c
@@ -0,0 +1,90 @@
+/* Return number of sections in the ELF file.
+ Copyright (C) 2002, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+__elf_getshdrnum_rdlock (elf, dst)
+ 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, dst)
+ 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/3rdparty/elfutils/libelf/elf_getshdrstrndx.c b/3rdparty/elfutils/libelf/elf_getshdrstrndx.c
new file mode 100644
index 0000000..6f8d66e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_getshdrstrndx.c
@@ -0,0 +1,229 @@
+/* Return section index of section header string table.
+ Copyright (C) 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <gelf.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+int
+elf_getshdrstrndx (elf, dst)
+ 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;
+
+ if (unlikely (pread_retry (elf->fildes, &shdr_mem,
+ sizeof (Elf32_Shdr), offset)
+ != sizeof (Elf32_Shdr)))
+ {
+ /* We must be able to read this ELF section header. */
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ 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;
+
+ if (unlikely (pread_retry (elf->fildes, &shdr_mem,
+ sizeof (Elf64_Shdr), offset)
+ != sizeof (Elf64_Shdr)))
+ {
+ /* We must be able to read this ELF section header. */
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ 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/3rdparty/elfutils/libelf/elf_gnu_hash.c b/3rdparty/elfutils/libelf/elf_gnu_hash.c
new file mode 100644
index 0000000..4c21857
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_gnu_hash.c
@@ -0,0 +1,47 @@
+/* GNU-style Hash function used in ELF implementations.
+ Copyright (C) 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation. */
+#include <dl-hash.h>
+
+unsigned long int
+elf_gnu_hash (string)
+ 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/3rdparty/elfutils/libelf/elf_hash.c b/3rdparty/elfutils/libelf/elf_hash.c
new file mode 100644
index 0000000..306ebc2
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_hash.c
@@ -0,0 +1,45 @@
+/* Hash function used in ELF implementations.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation. */
+#include <dl-hash.h>
+
+unsigned long int
+elf_hash (string)
+ const char *string;
+{
+ return _dl_elf_hash (string);
+}
+INTDEF(elf_hash)
diff --git a/3rdparty/elfutils/libelf/elf_kind.c b/3rdparty/elfutils/libelf/elf_kind.c
new file mode 100644
index 0000000..d8ab2fd
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_kind.c
@@ -0,0 +1,45 @@
+/* Return the kind of file associated with the descriptor.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Kind
+elf_kind (elf)
+ Elf *elf;
+{
+ return elf == NULL ? ELF_K_NONE : elf->kind;
+}
diff --git a/3rdparty/elfutils/libelf/elf_memory.c b/3rdparty/elfutils/libelf/elf_memory.c
new file mode 100644
index 0000000..08f85a1
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_memory.c
@@ -0,0 +1,52 @@
+/* Create descriptor for memory region.
+ Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf *
+elf_memory (image, size)
+ 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/3rdparty/elfutils/libelf/elf_ndxscn.c b/3rdparty/elfutils/libelf/elf_ndxscn.c
new file mode 100644
index 0000000..bd4bfbf
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_ndxscn.c
@@ -0,0 +1,48 @@
+/* Get index of section.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_ndxscn (scn)
+ Elf_Scn *scn;
+{
+ if (scn == NULL)
+ return SHN_UNDEF;
+
+ return scn->index;
+}
diff --git a/3rdparty/elfutils/libelf/elf_newdata.c b/3rdparty/elfutils/libelf/elf_newdata.c
new file mode 100644
index 0000000..90d1813
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_newdata.c
@@ -0,0 +1,109 @@
+/* Create new, empty section data.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#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);
+
+ 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
+ {
+ /* 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;
+
+ if (scn->data_list_rear == NULL)
+ /* We create new data without reading/converting the data from the
+ file. That is fine but we have to remember this. */
+ scn->data_list_rear = &scn->data_list;
+ }
+
+ /* Set the predefined values. */
+ result->data.d.d_version = __libelf_version;
+
+ 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/3rdparty/elfutils/libelf/elf_newscn.c b/3rdparty/elfutils/libelf/elf_newscn.c
new file mode 100644
index 0000000..6e0029e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_newscn.c
@@ -0,0 +1,163 @@
+/* Append new section.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_newscn (elf)
+ 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/3rdparty/elfutils/libelf/elf_next.c b/3rdparty/elfutils/libelf/elf_next.c
new file mode 100644
index 0000000..1f5c03c
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_next.c
@@ -0,0 +1,73 @@
+/* Advance in archive to next element.
+ Copyright (C) 1998-2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Cmd
+elf_next (elf)
+ 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/3rdparty/elfutils/libelf/elf_nextscn.c b/3rdparty/elfutils/libelf/elf_nextscn.c
new file mode 100644
index 0000000..0d2bd66
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_nextscn.c
@@ -0,0 +1,89 @@
+/* Get next section.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_nextscn (elf, scn)
+ Elf *elf;
+ Elf_Scn *scn;
+{
+ 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. */
+ if (elf->class == ELFCLASS32
+ || (offsetof (Elf, state.elf32.scns)
+ == offsetof (Elf, state.elf64.scns)))
+ {
+ if (elf->state.elf32.scns.cnt > 1)
+ result = &elf->state.elf32.scns.data[1];
+ }
+ else
+ {
+ if (elf->state.elf64.scns.cnt > 1)
+ result = &elf->state.elf64.scns.data[1];
+ }
+ }
+ else
+ {
+ Elf_ScnList *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/3rdparty/elfutils/libelf/elf_rand.c b/3rdparty/elfutils/libelf/elf_rand.c
new file mode 100644
index 0000000..cef4e44
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_rand.c
@@ -0,0 +1,65 @@
+/* Select specific element in archive.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_rand (elf, offset)
+ 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/3rdparty/elfutils/libelf/elf_rawdata.c b/3rdparty/elfutils/libelf/elf_rawdata.c
new file mode 100644
index 0000000..9672652
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_rawdata.c
@@ -0,0 +1,78 @@
+/* Return raw section content.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+elf_rawdata (scn, data)
+ 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/3rdparty/elfutils/libelf/elf_rawfile.c b/3rdparty/elfutils/libelf/elf_rawfile.c
new file mode 100644
index 0000000..dd71b88
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_rawfile.c
@@ -0,0 +1,69 @@
+/* Retrieve uninterpreted file contents.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_rawfile (elf, ptr)
+ 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/3rdparty/elfutils/libelf/elf_readall.c b/3rdparty/elfutils/libelf/elf_readall.c
new file mode 100644
index 0000000..0101618
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_readall.c
@@ -0,0 +1,152 @@
+/* Read all of the file associated with the descriptor.
+ Copyright (C) 1998-2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <system.h>
+#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 *
+__libelf_readall (elf)
+ 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/3rdparty/elfutils/libelf/elf_scnshndx.c b/3rdparty/elfutils/libelf/elf_scnshndx.c
new file mode 100644
index 0000000..5b783fa
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#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/3rdparty/elfutils/libelf/elf_strptr.c b/3rdparty/elfutils/libelf/elf_strptr.c
new file mode 100644
index 0000000..1f40429
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_strptr.c
@@ -0,0 +1,161 @@
+/* Return string pointer from string section.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008, 2009 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_strptr (elf, idx, offset)
+ 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;
+ }
+ }
+
+ if (elf->class == ELFCLASS32)
+ {
+ if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB))
+ {
+ /* This is no string section. */
+ __libelf_seterrno (ELF_E_INVALID_SECTION);
+ goto out;
+ }
+
+ if (unlikely (offset >= strscn->shdr.e32->sh_size))
+ {
+ /* The given offset is too big, it is beyond this section. */
+ __libelf_seterrno (ELF_E_OFFSET_RANGE);
+ goto out;
+ }
+ }
+ else
+ {
+ if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB))
+ {
+ /* This is no string section. */
+ __libelf_seterrno (ELF_E_INVALID_SECTION);
+ goto out;
+ }
+
+ if (unlikely (offset >= strscn->shdr.e64->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 (likely (strscn->rawdata_base != NULL))
+ // XXX Is this correct if a file is read and then new data is added
+ // XXX to the string section? Likely needs to check offset against
+ // XXX size of rawdata_base buffer and then iterate over rest of the
+ // XXX list.
+ result = &strscn->rawdata_base[offset];
+ 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)
+ {
+ result = (char *) dl->data.d.d_buf + (offset - dl->data.d.d_off);
+ break;
+ }
+
+ dl = dl->next;
+ }
+ }
+
+ out:
+ rwlock_unlock (elf->lock);
+
+ return result;
+}
+INTDEF(elf_strptr)
diff --git a/3rdparty/elfutils/libelf/elf_update.c b/3rdparty/elfutils/libelf/elf_update.c
new file mode 100644
index 0000000..54c20f5
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_update.c
@@ -0,0 +1,199 @@
+/* Update data structures for changes and write them out.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "libelfP.h"
+
+
+static off_t
+write_file (Elf *elf, off_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;
+ }
+
+ if (elf->map_address != NULL)
+ {
+ /* 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;
+ }
+
+ 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;
+}
+
+
+off_t
+elf_update (elf, cmd)
+ Elf *elf;
+ Elf_Cmd cmd;
+{
+ size_t shnum;
+ off_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/3rdparty/elfutils/libelf/elf_version.c b/3rdparty/elfutils/libelf/elf_version.c
new file mode 100644
index 0000000..dcb6758
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elf_version.c
@@ -0,0 +1,70 @@
+/* Coordinate ELF library and application versions.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+
+/* Is the version initialized? */
+int __libelf_version_initialized;
+
+/* Currently selected version. */
+unsigned int __libelf_version = EV_CURRENT;
+
+
+unsigned int
+elf_version (version)
+ unsigned int version;
+{
+ if (version == EV_NONE)
+ return __libelf_version;
+
+ if (likely (version < EV_NUM))
+ {
+ /* Phew, we know this version. */
+ unsigned int last_version = __libelf_version;
+
+ /* Store the new version. */
+ __libelf_version = version;
+
+ /* Signal that the version is now initialized. */
+ __libelf_version_initialized = 1;
+
+ /* And return the last version. */
+ return last_version;
+ }
+
+ /* We cannot handle this version. */
+ __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+ return EV_NONE;
+}
+INTDEF(elf_version)
diff --git a/3rdparty/elfutils/libelf/elfheaders.pri b/3rdparty/elfutils/libelf/elfheaders.pri
new file mode 100644
index 0000000..2597ec8
--- /dev/null
+++ b/3rdparty/elfutils/libelf/elfheaders.pri
@@ -0,0 +1,17 @@
+HEADERS += \
+ $$PWD/abstract.h \
+ $$PWD/common.h \
+ $$PWD/dl-hash.h \
+ $$PWD/elf-knowledge.h \
+ $$PWD/elf.h \
+ $$PWD/exttypes.h \
+ $$PWD/gelf_xlate.h \
+ $$PWD/gelf.h \
+ $$PWD/gnuhash_xlate.h \
+ $$PWD/libelf.h \
+ $$PWD/libelfP.h \
+ $$PWD/nlist.h \
+ $$PWD/note_xlate.h \
+ $$PWD/version_xlate.h
+
+INCLUDEPATH += $$PWD
diff --git a/3rdparty/elfutils/libelf/exttypes.h b/3rdparty/elfutils/libelf/exttypes.h
new file mode 100644
index 0000000..8cb2aae
--- /dev/null
+++ b/3rdparty/elfutils/libelf/exttypes.h
@@ -0,0 +1,102 @@
+/* External ELF types.
+ Copyright (C) 1998-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#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_);
+
+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_);
+
+#undef START
+#undef END
+#undef TYPE_NAME
+#undef TYPE_EXTRA
+#undef TYPE_XLATE
+
+#endif /* exttypes.h */
diff --git a/3rdparty/elfutils/libelf/gelf.h b/3rdparty/elfutils/libelf/gelf.h
new file mode 100644
index 0000000..e3f0740
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf.h
@@ -0,0 +1,332 @@
+/* This file defines generic ELF types, structures, and macros.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _GELF_H
+#define _GELF_H 1
+
+#include <libelf.h>
+
+
+#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;
+
+/* Dynamic section entry. */
+typedef Elf64_Dyn GElf_Dyn;
+
+
+/* Version definition sections. */
+typedef Elf64_Verdef GElf_Verdef;
+
+/* Auxialiary 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. */
+extern unsigned long int 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. */
+extern unsigned long int gelf_newphdr (Elf *__elf, size_t __phnum);
+
+
+/* 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/3rdparty/elfutils/libelf/gelf_checksum.c b/3rdparty/elfutils/libelf/gelf_checksum.c
new file mode 100644
index 0000000..4906782
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_checksum.c
@@ -0,0 +1,49 @@
+/* Convert from file to memory representation. Generic ELF version.
+ Copyright (C) 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+long int
+gelf_checksum (elf)
+ Elf *elf;
+{
+ if (elf == NULL)
+ return -1l;
+
+ return (elf->class == ELFCLASS32
+ ? INTUSE(elf32_checksum) (elf) : INTUSE(elf64_checksum) (elf));
+}
diff --git a/3rdparty/elfutils/libelf/gelf_fsize.c b/3rdparty/elfutils/libelf/gelf_fsize.c
new file mode 100644
index 0000000..a9d2288
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_fsize.c
@@ -0,0 +1,111 @@
+/* Return the size of an object file type.
+ Copyright (C) 1998-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+/* These are the sizes for all the known types. */
+const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+{
+ /* We have no entry for EV_NONE since we have to set an error. */
+ [EV_CURRENT - 1] = {
+ [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)), \
+ [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_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD)
+ TYPE_SIZES (32)
+ },
+ [ELFCLASS64 - 1] = {
+ TYPE_SIZES (64)
+ }
+ }
+};
+
+
+size_t
+gelf_fsize (elf, type, count, version)
+ 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_NONE || version >= EV_NUM)
+ {
+ __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+ return 0;
+ }
+
+ if (type >= ELF_T_NUM)
+ {
+ __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+ return 0;
+ }
+
+#if EV_NUM != 2
+ return count * __libelf_type_sizes[version - 1][elf->class - 1][type];
+#else
+ return count * __libelf_type_sizes[0][elf->class - 1][type];
+#endif
+}
+INTDEF(gelf_fsize)
diff --git a/3rdparty/elfutils/libelf/gelf_getauxv.c b/3rdparty/elfutils/libelf/gelf_getauxv.c
new file mode 100644
index 0000000..a2f04e7
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getauxv.c
@@ -0,0 +1,110 @@
+/* Get information from auxiliary vector at the given index.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_auxv_t *
+gelf_getauxv (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getclass.c b/3rdparty/elfutils/libelf/gelf_getclass.c
new file mode 100644
index 0000000..53759dc
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getclass.c
@@ -0,0 +1,45 @@
+/* Return the class of file associated with the descriptor.
+ Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_getclass (elf)
+ Elf *elf;
+{
+ return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class;
+}
diff --git a/3rdparty/elfutils/libelf/gelf_getdyn.c b/3rdparty/elfutils/libelf/gelf_getdyn.c
new file mode 100644
index 0000000..c366fd5
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getdyn.c
@@ -0,0 +1,111 @@
+/* Get information from dynamic table at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Dyn *
+gelf_getdyn (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getehdr.c b/3rdparty/elfutils/libelf/gelf_getehdr.c
new file mode 100644
index 0000000..ea83fc0
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getehdr.c
@@ -0,0 +1,111 @@
+/* Get ELF header.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Ehdr *
+__gelf_getehdr_rdlock (elf, dest)
+ 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, dest)
+ 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/3rdparty/elfutils/libelf/gelf_getlib.c b/3rdparty/elfutils/libelf/gelf_getlib.c
new file mode 100644
index 0000000..880817e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getlib.c
@@ -0,0 +1,80 @@
+/* Get library from table at the given index.
+ Copyright (C) 2004, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Lib *
+gelf_getlib (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getmove.c b/3rdparty/elfutils/libelf/gelf_getmove.c
new file mode 100644
index 0000000..b81d61f
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getmove.c
@@ -0,0 +1,82 @@
+/* Get move structure at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+GElf_Move *
+gelf_getmove (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getnote.c b/3rdparty/elfutils/libelf/gelf_getnote.c
new file mode 100644
index 0000000..7dc8215
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getnote.c
@@ -0,0 +1,104 @@
+/* Get note information at the supplied offset.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+size_t
+gelf_getnote (data, offset, result, name_offset, desc_offset)
+ 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))
+ {
+ __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;
+
+ /* Include padding. Check below for overflow. */
+ GElf_Word namesz = NOTE_ALIGN (n->n_namesz);
+ GElf_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+ if (unlikely (offset > data->d_size
+ || data->d_size - offset < namesz
+ || (namesz == 0 && n->n_namesz != 0)))
+ offset = 0;
+ else
+ {
+ *name_offset = offset;
+ offset += namesz;
+ 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/3rdparty/elfutils/libelf/gelf_getphdr.c b/3rdparty/elfutils/libelf/gelf_getphdr.c
new file mode 100644
index 0000000..3bf7123
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getphdr.c
@@ -0,0 +1,142 @@
+/* Return program header table entry.
+ Copyright (C) 1998-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "libelfP.h"
+
+
+GElf_Phdr *
+gelf_getphdr (elf, ndx, dst)
+ 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 (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;
+ }
+
+ /* 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 (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;
+ }
+
+ /* 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/3rdparty/elfutils/libelf/gelf_getrel.c b/3rdparty/elfutils/libelf/gelf_getrel.c
new file mode 100644
index 0000000..1f786ff
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getrel.c
@@ -0,0 +1,102 @@
+/* Get 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rel *
+gelf_getrel (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getrela.c b/3rdparty/elfutils/libelf/gelf_getrela.c
new file mode 100644
index 0000000..cead7ee
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getrela.c
@@ -0,0 +1,103 @@
+/* Get 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rela *
+gelf_getrela (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getshdr.c b/3rdparty/elfutils/libelf/gelf_getshdr.c
new file mode 100644
index 0000000..4a48cb6
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getshdr.c
@@ -0,0 +1,105 @@
+/* Return section header.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Shdr *
+gelf_getshdr (scn, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getsym.c b/3rdparty/elfutils/libelf/gelf_getsym.c
new file mode 100644
index 0000000..a141c2d
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getsym.c
@@ -0,0 +1,117 @@
+/* Get symbol information from symbol table at the given index.
+ Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsym (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getsyminfo.c b/3rdparty/elfutils/libelf/gelf_getsyminfo.c
new file mode 100644
index 0000000..8d7da7f
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getsyminfo.c
@@ -0,0 +1,80 @@
+/* Get additional symbol information from symbol table at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Syminfo *
+gelf_getsyminfo (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getsymshndx.c b/3rdparty/elfutils/libelf/gelf_getsymshndx.c
new file mode 100644
index 0000000..c19e876
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getsymshndx.c
@@ -0,0 +1,140 @@
+/* Get symbol information and separate section index from symbol table
+ at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsymshndx (symdata, shndxdata, ndx, dst, dstshndx)
+ 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/3rdparty/elfutils/libelf/gelf_getverdaux.c b/3rdparty/elfutils/libelf/gelf_getverdaux.c
new file mode 100644
index 0000000..d125d9e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getverdaux.c
@@ -0,0 +1,82 @@
+/* Get additional symbol version definition information at the given offset.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdaux *
+gelf_getverdaux (data, offset, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getverdef.c b/3rdparty/elfutils/libelf/gelf_getverdef.c
new file mode 100644
index 0000000..59a3214
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getverdef.c
@@ -0,0 +1,81 @@
+/* Get symbol version definition information at the given offset.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdef *
+gelf_getverdef (data, offset, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getvernaux.c b/3rdparty/elfutils/libelf/gelf_getvernaux.c
new file mode 100644
index 0000000..8ebf56a
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getvernaux.c
@@ -0,0 +1,84 @@
+/* Get additional required symbol version information at the given offset.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Vernaux *
+gelf_getvernaux (data, offset, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getverneed.c b/3rdparty/elfutils/libelf/gelf_getverneed.c
new file mode 100644
index 0000000..95fd11f
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getverneed.c
@@ -0,0 +1,84 @@
+/* Get required symbol version information at the given offset.
+ Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verneed *
+gelf_getverneed (data, offset, dst)
+ 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/3rdparty/elfutils/libelf/gelf_getversym.c b/3rdparty/elfutils/libelf/gelf_getversym.c
new file mode 100644
index 0000000..fe8dc62
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_getversym.c
@@ -0,0 +1,89 @@
+/* Get symbol version information at the given index.
+ Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Versym *
+gelf_getversym (data, ndx, dst)
+ 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/3rdparty/elfutils/libelf/gelf_newehdr.c b/3rdparty/elfutils/libelf/gelf_newehdr.c
new file mode 100644
index 0000000..e9f7a58
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_newehdr.c
@@ -0,0 +1,48 @@
+/* Create new ELF header.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+unsigned long int
+gelf_newehdr (elf, class)
+ Elf *elf;
+ int class;
+{
+ return (class == ELFCLASS32
+ ? (unsigned long int) INTUSE(elf32_newehdr) (elf)
+ : (unsigned long int) INTUSE(elf64_newehdr) (elf));
+}
diff --git a/3rdparty/elfutils/libelf/gelf_newphdr.c b/3rdparty/elfutils/libelf/gelf_newphdr.c
new file mode 100644
index 0000000..b634037
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_newphdr.c
@@ -0,0 +1,48 @@
+/* Create new ELF program header.
+ Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+unsigned long int
+gelf_newphdr (elf, phnum)
+ Elf *elf;
+ size_t phnum;
+{
+ return (elf->class == ELFCLASS32
+ ? (unsigned long int) INTUSE(elf32_newphdr) (elf, phnum)
+ : (unsigned long int) INTUSE(elf64_newphdr) (elf, phnum));
+}
diff --git a/3rdparty/elfutils/libelf/gelf_offscn.c b/3rdparty/elfutils/libelf/gelf_offscn.c
new file mode 100644
index 0000000..62d12e4
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_offscn.c
@@ -0,0 +1,57 @@
+/* Create new ELF header.
+ Copyright (C) 2005 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+gelf_offscn (elf, offset)
+ 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/3rdparty/elfutils/libelf/gelf_update_auxv.c b/3rdparty/elfutils/libelf/gelf_update_auxv.c
new file mode 100644
index 0000000..dd8f472
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_auxv.c
@@ -0,0 +1,114 @@
+/* Update information in dynamic table at the given index.
+ 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_auxv (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_dyn.c b/3rdparty/elfutils/libelf/gelf_update_dyn.c
new file mode 100644
index 0000000..2eb526e
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_dyn.c
@@ -0,0 +1,110 @@
+/* Update information in dynamic table at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_dyn (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_ehdr.c b/3rdparty/elfutils/libelf/gelf_update_ehdr.c
new file mode 100644
index 0000000..73d5af7
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#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/3rdparty/elfutils/libelf/gelf_update_lib.c b/3rdparty/elfutils/libelf/gelf_update_lib.c
new file mode 100644
index 0000000..1c8c23d
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_lib.c
@@ -0,0 +1,78 @@
+/* Update library in table at the given index.
+ Copyright (C) 2004, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_lib (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_move.c b/3rdparty/elfutils/libelf/gelf_update_move.c
new file mode 100644
index 0000000..ad2ca6a
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_move.c
@@ -0,0 +1,80 @@
+/* Update move structure at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_move (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_phdr.c b/3rdparty/elfutils/libelf/gelf_update_phdr.c
new file mode 100644
index 0000000..a848677
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#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/3rdparty/elfutils/libelf/gelf_update_rel.c b/3rdparty/elfutils/libelf/gelf_update_rel.c
new file mode 100644
index 0000000..14f62e9
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#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/3rdparty/elfutils/libelf/gelf_update_rela.c b/3rdparty/elfutils/libelf/gelf_update_rela.c
new file mode 100644
index 0000000..8825270
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#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/3rdparty/elfutils/libelf/gelf_update_shdr.c b/3rdparty/elfutils/libelf/gelf_update_shdr.c
new file mode 100644
index 0000000..c93c6ec
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#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/3rdparty/elfutils/libelf/gelf_update_sym.c b/3rdparty/elfutils/libelf/gelf_update_sym.c
new file mode 100644
index 0000000..278129c
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_sym.c
@@ -0,0 +1,119 @@
+/* Update symbol information in symbol table at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_sym (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_syminfo.c b/3rdparty/elfutils/libelf/gelf_update_syminfo.c
new file mode 100644
index 0000000..640a1ed
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_syminfo.c
@@ -0,0 +1,86 @@
+/* Update additional symbol information in symbol table at the given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_syminfo (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_symshndx.c b/3rdparty/elfutils/libelf/gelf_update_symshndx.c
new file mode 100644
index 0000000..5e2c7f7
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_symshndx.c
@@ -0,0 +1,149 @@
+/* Update symbol information and section index in symbol table at the
+ given index.
+ Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_symshndx (symdata, shndxdata, ndx, src, srcshndx)
+ 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/3rdparty/elfutils/libelf/gelf_update_verdaux.c b/3rdparty/elfutils/libelf/gelf_update_verdaux.c
new file mode 100644
index 0000000..b377d40
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_verdaux.c
@@ -0,0 +1,81 @@
+/* Update additional symbol version definition information.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdaux (data, offset, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_verdef.c b/3rdparty/elfutils/libelf/gelf_update_verdef.c
new file mode 100644
index 0000000..d591a4f
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_verdef.c
@@ -0,0 +1,81 @@
+/* Update symbol version definition information.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdef (data, offset, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_vernaux.c b/3rdparty/elfutils/libelf/gelf_update_vernaux.c
new file mode 100644
index 0000000..1f691b0
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_vernaux.c
@@ -0,0 +1,81 @@
+/* Update additional required symbol version information.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_vernaux (data, offset, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_verneed.c b/3rdparty/elfutils/libelf/gelf_update_verneed.c
new file mode 100644
index 0000000..713c017
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_verneed.c
@@ -0,0 +1,81 @@
+/* Update required symbol version information.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verneed (data, offset, src)
+ 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/3rdparty/elfutils/libelf/gelf_update_versym.c b/3rdparty/elfutils/libelf/gelf_update_versym.c
new file mode 100644
index 0000000..03a3c5a
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_update_versym.c
@@ -0,0 +1,80 @@
+/* Update symbol version information.
+ Copyright (C) 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_versym (data, ndx, src)
+ 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/3rdparty/elfutils/libelf/gelf_xlate.c b/3rdparty/elfutils/libelf/gelf_xlate.c
new file mode 100644
index 0000000..c417051
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_xlate.c
@@ -0,0 +1,214 @@
+/* Transformation functions for ELF data types.
+ Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <byteswap.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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)))
+{
+ 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"
+
+
+/* Now the externally visible table with the function pointers. */
+const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+{
+ [EV_CURRENT - 1] = {
+ [EV_CURRENT - 1] = {
+ [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_note, \
+ [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)
+ define_xfcts (32),
+ [ELF_T_GNUHASH] = Elf32_cvt_Word
+ },
+ [ELFCLASS64 - 1] = {
+ define_xfcts (64),
+ [ELF_T_GNUHASH] = elf_cvt_gnuhash
+ }
+ }
+ }
+};
+/* For now we only handle the case where the memory representation is the
+ same as the file representation. Should this change we have to define
+ separate functions. For now reuse them. */
+strong_alias (__elf_xfctstom, __elf_xfctstof)
diff --git a/3rdparty/elfutils/libelf/gelf_xlate.h b/3rdparty/elfutils/libelf/gelf_xlate.h
new file mode 100644
index 0000000..f11eb90
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_xlate.h
@@ -0,0 +1,56 @@
+/* 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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+
+/* 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)
+
+
+/* Prepare for the next round. */
+#undef LIBELFBITS
diff --git a/3rdparty/elfutils/libelf/gelf_xlatetof.c b/3rdparty/elfutils/libelf/gelf_xlatetof.c
new file mode 100644
index 0000000..3366bdc
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_xlatetof.c
@@ -0,0 +1,53 @@
+/* Convert from memory to file representation. Generic ELF version.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetof (elf, dest, src, encode)
+ 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/3rdparty/elfutils/libelf/gelf_xlatetom.c b/3rdparty/elfutils/libelf/gelf_xlatetom.c
new file mode 100644
index 0000000..c3e812f
--- /dev/null
+++ b/3rdparty/elfutils/libelf/gelf_xlatetom.c
@@ -0,0 +1,53 @@
+/* Convert from file to memory representation. Generic ELF version.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetom (elf, dest, src, encode)
+ 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/3rdparty/elfutils/libelf/gnuhash_xlate.h b/3rdparty/elfutils/libelf/gnuhash_xlate.h
new file mode 100644
index 0000000..6faf113
--- /dev/null
+++ b/3rdparty/elfutils/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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <gelf.h>
+
+#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/3rdparty/elfutils/libelf/libelf.h b/3rdparty/elfutils/libelf/libelf.h
new file mode 100644
index 0000000..5a2b3af
--- /dev/null
+++ b/3rdparty/elfutils/libelf/libelf.h
@@ -0,0 +1,396 @@
+/* Interface for libelf.
+ Copyright (C) 1998-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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBELF_H
+#define _LIBELF_H 1
+
+#include <sys/types.h>
+
+/* Get the ELF types. */
+#include <elf.h>
+
+
+/* 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, ... */
+ /* 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. */
+ loff_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
+};
+
+
+/* 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. */
+ loff_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 loff_t elf_update (Elf *__elf, Elf_Cmd __cmd);
+
+/* Determine what kind of file is associated with ELF. */
+extern Elf_Kind elf_kind (Elf *__elf) __attribute__ ((__pure__));
+
+/* Get the base offset for an object file. */
+extern loff_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)
+ __attribute__ ((__deprecated__));
+
+
+/* Get the section index of the section header string table in the ELF
+ file. If the index cannot be represented in the e_shnum 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_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_getshstrndx (Elf *__elf, size_t *__dst)
+ __attribute__ ((__deprecated__));
+
+
+/* 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);
+
+
+/* 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. */
+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,
+ loff_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 loff_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)
+ __attribute__ ((__const__));
+/* Similar but this time the binary calls is ELFCLASS64. */
+extern size_t elf64_fsize (Elf_Type __type, size_t __count,
+ unsigned int __version)
+ __attribute__ ((__const__));
+
+
+/* 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)
+ __attribute__ ((__pure__));
+
+/* Compute hash value using the GNU-specific hash function. */
+extern unsigned long int elf_gnu_hash (const char *__string)
+ __attribute__ ((__pure__));
+
+
+/* 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/3rdparty/elfutils/libelf/libelf.pro b/3rdparty/elfutils/libelf/libelf.pro
new file mode 100644
index 0000000..fc76549
--- /dev/null
+++ b/3rdparty/elfutils/libelf/libelf.pro
@@ -0,0 +1,95 @@
+TEMPLATE = lib
+CONFIG += staticlib
+TARGET = ../elf
+
+include(../elfutils.pri)
+include(elfheaders.pri)
+
+SOURCES += \
+ $$PWD/elf_begin.c \
+ $$PWD/elf_clone.c \
+ $$PWD/elf_cntl.c \
+ $$PWD/elf_end.c \
+ $$PWD/elf_error.c \
+ $$PWD/elf_fill.c \
+ $$PWD/elf_flagdata.c \
+ $$PWD/elf_flagehdr.c \
+ $$PWD/elf_flagelf.c \
+ $$PWD/elf_flagphdr.c \
+ $$PWD/elf_flagscn.c \
+ $$PWD/elf_flagshdr.c \
+ $$PWD/elf_getarhdr.c \
+ $$PWD/elf_getaroff.c \
+ $$PWD/elf_getarsym.c \
+ $$PWD/elf_getbase.c \
+ $$PWD/elf_getdata_rawchunk.c \
+ $$PWD/elf_getdata.c \
+ $$PWD/elf_getident.c \
+ $$PWD/elf_getphdrnum.c \
+ $$PWD/elf_getscn.c \
+ $$PWD/elf_getshdrnum.c \
+ $$PWD/elf_getshdrstrndx.c \
+ $$PWD/elf_gnu_hash.c \
+ $$PWD/elf_hash.c \
+ $$PWD/elf_kind.c \
+ $$PWD/elf_memory.c \
+ $$PWD/elf_ndxscn.c \
+ $$PWD/elf_newdata.c \
+ $$PWD/elf_newscn.c \
+ $$PWD/elf_next.c \
+ $$PWD/elf_nextscn.c \
+ $$PWD/elf_rand.c \
+ $$PWD/elf_rawdata.c \
+ $$PWD/elf_rawfile.c \
+ $$PWD/elf_readall.c \
+ $$PWD/elf_scnshndx.c \
+ $$PWD/elf_strptr.c \
+ $$PWD/elf_update.c \
+ $$PWD/elf_version.c \
+ $$PWD/gelf_checksum.c \
+ $$PWD/gelf_fsize.c \
+ $$PWD/gelf_getauxv.c \
+ $$PWD/gelf_getclass.c \
+ $$PWD/gelf_getdyn.c \
+ $$PWD/gelf_getehdr.c \
+ $$PWD/gelf_getlib.c \
+ $$PWD/gelf_getmove.c \
+ $$PWD/gelf_getnote.c \
+ $$PWD/gelf_getphdr.c \
+ $$PWD/gelf_getrel.c \
+ $$PWD/gelf_getrela.c \
+ $$PWD/gelf_getshdr.c \
+ $$PWD/gelf_getsym.c \
+ $$PWD/gelf_getsyminfo.c \
+ $$PWD/gelf_getsymshndx.c \
+ $$PWD/gelf_getverdaux.c \
+ $$PWD/gelf_getverdef.c \
+ $$PWD/gelf_getvernaux.c \
+ $$PWD/gelf_getverneed.c \
+ $$PWD/gelf_getversym.c \
+ $$PWD/gelf_newehdr.c \
+ $$PWD/gelf_newphdr.c \
+ $$PWD/gelf_offscn.c \
+ $$PWD/gelf_update_auxv.c \
+ $$PWD/gelf_update_dyn.c \
+ $$PWD/gelf_update_ehdr.c \
+ $$PWD/gelf_update_lib.c \
+ $$PWD/gelf_update_move.c \
+ $$PWD/gelf_update_phdr.c \
+ $$PWD/gelf_update_rel.c \
+ $$PWD/gelf_update_rela.c \
+ $$PWD/gelf_update_shdr.c \
+ $$PWD/gelf_update_sym.c \
+ $$PWD/gelf_update_syminfo.c \
+ $$PWD/gelf_update_symshndx.c \
+ $$PWD/gelf_update_verdaux.c \
+ $$PWD/gelf_update_verdef.c \
+ $$PWD/gelf_update_vernaux.c \
+ $$PWD/gelf_update_verneed.c \
+ $$PWD/gelf_update_versym.c \
+ $$PWD/gelf_xlate.c \
+ $$PWD/gelf_xlatetof.c \
+ $$PWD/gelf_xlatetom.c \
+ $$PWD/libelf_crc32.c \
+ $$PWD/libelf_next_prime.c \
+ $$PWD/nlist.c
diff --git a/3rdparty/elfutils/libelf/libelfP.h b/3rdparty/elfutils/libelf/libelfP.h
new file mode 100644
index 0000000..52cf745
--- /dev/null
+++ b/3rdparty/elfutils/libelf/libelfP.h
@@ -0,0 +1,594 @@
+/* Internal interfaces for libelf.
+ Copyright (C) 1998-2010 Red Hat, Inc.
+ This file is part of elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBELFP_H
+#define _LIBELFP_H 1
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ar.h>
+#include <gelf.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* 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_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,
+ /* Keep this as the last entry. */
+ ELF_E_NUM
+};
+
+
+/* The visible `Elf_Data' type is not sufficent 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? */
+
+ char *rawdata_base; /* The unmodified data of the section. */
+ char *data_base; /* The converted data of the section. */
+
+ 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. */
+ off_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. */
+ off64_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. */
+ off64_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. */
+ off64_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. */
+ off_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[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+extern const xfct_t __elf_xfctstof[EV_NUM - 1][EV_NUM - 1][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[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+/* We often have to access the size for a type in the current version. */
+#if EV_NUM != 2
+# define elf_typesize(class,type,n) \
+ elfw2(class,fsize) (type, n, __libelf_version)
+#else
+# define elf_typesize(class,type,n) \
+ (__libelf_type_sizes[EV_CURRENT - 1][ELFW(ELFCLASS,class) - 1][type] * n)
+#endif
+
+/* Currently selected version of the ELF specification. */
+extern unsigned int __libelf_version attribute_hidden;
+
+/* The byte value used for filling gaps. */
+extern int __libelf_fill_byte attribute_hidden;
+
+/* Nonzero if the version was set. */
+extern int __libelf_version_initialized attribute_hidden;
+
+/* Index for __libelf_type_sizes et al. */
+#if EV_NUM == 2
+# define LIBELF_EV_IDX 0
+#else
+# define LIBELF_EV_IDX (__libelf_version - 1)
+#endif
+
+#if !ALLOW_UNALIGNED
+/* Array with alignment requirements of the internal types indexed by ELF
+ version, binary class, and type. */
+extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+# define __libelf_type_align(class, type) \
+ (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1)
+#else
+# define __libelf_type_align(class, type) 1
+#endif
+
+/* The libelf API does not have such a function but it is still useful.
+ Get the memory size for the given type.
+
+ These functions cannot be marked internal since they are aliases
+ of the export elfXX_fsize functions.*/
+extern size_t __elf32_msize (Elf_Type __type, size_t __count,
+ unsigned int __version);
+extern size_t __elf64_msize (Elf_Type __type, size_t __count,
+ unsigned int __version);
+
+
+/* Create Elf descriptor from memory image. */
+extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address,
+ off_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 off_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop,
+ size_t shnum) internal_function;
+extern off_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_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;
+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__, visibility ("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;
+
+
+/* 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. */
+#define NOTE_ALIGN(n) (((n) + 3) & -4U)
+
+/* Convenience macro. */
+#define INVALID_NDX(ndx, type, data) \
+ unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
+
+#endif /* libelfP.h */
diff --git a/3rdparty/elfutils/libelf/libelf_crc32.c b/3rdparty/elfutils/libelf/libelf_crc32.c
new file mode 100644
index 0000000..1426faf
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32 attribute_hidden __libelf_crc32
+#define LIB_SYSTEM_H 1
+#include <libelf.h>
+#include "../lib/crc32.c"
diff --git a/3rdparty/elfutils/libelf/libelf_next_prime.c b/3rdparty/elfutils/libelf/libelf_next_prime.c
new file mode 100644
index 0000000..05229c3
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define next_prime attribute_hidden __libelf_next_prime
+#include "../lib/next_prime.c"
diff --git a/3rdparty/elfutils/libelf/nlist.c b/3rdparty/elfutils/libelf/nlist.c
new file mode 100644
index 0000000..41e5ff6
--- /dev/null
+++ b/3rdparty/elfutils/libelf/nlist.c
@@ -0,0 +1,243 @@
+/* Extract symbol list from binary.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <nlist.h>
+#include <unistd.h>
+
+#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 <fixedsizehash.h>
+
+
+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
+ if it hasn't happened yet. */
+ if (__libelf_version_initialized == 0)
+ 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);
+ /* 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, data->d_version));
+
+ /* 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/3rdparty/elfutils/libelf/nlist.h b/3rdparty/elfutils/libelf/nlist.h
new file mode 100644
index 0000000..5990918
--- /dev/null
+++ b/3rdparty/elfutils/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 <http://www.gnu.org/licenses/>. */
+
+#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/3rdparty/elfutils/libelf/note_xlate.h b/3rdparty/elfutils/libelf/note_xlate.h
new file mode 100644
index 0000000..62c6f63
--- /dev/null
+++ b/3rdparty/elfutils/libelf/note_xlate.h
@@ -0,0 +1,64 @@
+/* Conversion functions for notes.
+ 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 <http://www.gnu.org/licenses/>. */
+
+static void
+elf_cvt_note (void *dest, const void *src, size_t len, int encode)
+{
+ assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+ while (len >= sizeof (Elf32_Nhdr))
+ {
+ (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
+ encode);
+ const Elf32_Nhdr *n = encode ? src : dest;
+ Elf32_Word namesz = NOTE_ALIGN (n->n_namesz);
+ Elf32_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+ len -= sizeof *n;
+ src += sizeof *n;
+ dest += sizeof *n;
+
+ if (namesz > len)
+ break;
+ len -= namesz;
+ if (descsz > len)
+ break;
+ len -= descsz;
+
+ if (src != dest)
+ memcpy (dest, src, namesz + descsz);
+
+ src += namesz + descsz;
+ dest += namesz + descsz;
+ }
+
+ /* Copy opver any leftover data unconcerted. Probably part of
+ truncated name/desc data. */
+ if (unlikely (len > 0) && src != dest)
+ memcpy (dest, src, len);
+}
diff --git a/3rdparty/elfutils/libelf/version_xlate.h b/3rdparty/elfutils/libelf/version_xlate.h
new file mode 100644
index 0000000..16eaa19
--- /dev/null
+++ b/3rdparty/elfutils/libelf/version_xlate.h
@@ -0,0 +1,220 @@
+/* Conversion functions for versioning information.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <gelf.h>
+
+#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;
+
+ 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;
+
+ 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/3rdparty/elfutils/version.h b/3rdparty/elfutils/version.h
new file mode 100644
index 0000000..7139c45
--- /dev/null
+++ b/3rdparty/elfutils/version.h
@@ -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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _ELFUTILS_VERSION_H
+#define _ELFUTILS_VERSION_H 1
+
+#define _ELFUTILS_VERSION 161
+
+#define _ELFUTILS_PREREQ(major, minor) \
+ (_ELFUTILS_VERSION >= ((major) * 1000 + (minor)))
+
+#endif /* elfutils/version.h */
diff --git a/app/app.pro b/app/app.pro
new file mode 100644
index 0000000..36bf0fe
--- /dev/null
+++ b/app/app.pro
@@ -0,0 +1,52 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2014-08-14T10:44:20
+#
+#-------------------------------------------------
+
+QT += core network
+
+QT -= gui
+
+QMAKE_LFLAGS += -Wl,-rpath,\'\$\$ORIGIN/elfutils/backends\'
+LIBS += -Wl,--start-group \
+ ../3rdparty/elfutils/libdw.a \
+ ../3rdparty/elfutils/libdwfl.a \
+ ../3rdparty/elfutils/libelf.a \
+ ../3rdparty/elfutils/libelf32.a \
+ ../3rdparty/elfutils/libelf64.a \
+ ../3rdparty/elfutils/libebl.a \
+ ../3rdparty/elfutils/libdwelf.a \
+ -Wl,--end-group \
+ -Wl,-Bstatic -lbfd -Wl,-Bdynamic -lz -ldl -liberty
+
+TARGET = ../perfparser
+CONFIG += console c++11
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+SOURCES += main.cpp \
+ perfattributes.cpp \
+ perfheader.cpp \
+ perffilesection.cpp \
+ perffeatures.cpp \
+ perfdata.cpp \
+ perfunwind.cpp \
+ perfregisterinfo.cpp \
+ perfstdin.cpp
+
+HEADERS += \
+ perfattributes.h \
+ perfheader.h \
+ perffilesection.h \
+ perffeatures.h \
+ perfdata.h \
+ perfunwind.h \
+ perfregisterinfo.h \
+ perfstdin.h
+
+include(../3rdparty/elfutils/elfutils.pri)
+include(../3rdparty/elfutils/libdwfl/dwflheaders.pri)
+include(../3rdparty/elfutils/libebl/eblheaders.pri)
+include(../3rdparty/elfutils/libdwelf/dwelfheaders.pri)
diff --git a/main.cpp b/app/main.cpp
index 7a8310e..7a8310e 100644
--- a/main.cpp
+++ b/app/main.cpp
diff --git a/perfattributes.cpp b/app/perfattributes.cpp
index 94d59fc..94d59fc 100644
--- a/perfattributes.cpp
+++ b/app/perfattributes.cpp
diff --git a/perfattributes.h b/app/perfattributes.h
index f0c244e..f0c244e 100644
--- a/perfattributes.h
+++ b/app/perfattributes.h
diff --git a/perfdata.cpp b/app/perfdata.cpp
index 6a71b3f..6a71b3f 100644
--- a/perfdata.cpp
+++ b/app/perfdata.cpp
diff --git a/perfdata.h b/app/perfdata.h
index 3c85390..3c85390 100644
--- a/perfdata.h
+++ b/app/perfdata.h
diff --git a/perffeatures.cpp b/app/perffeatures.cpp
index f9f26bb..f9f26bb 100644
--- a/perffeatures.cpp
+++ b/app/perffeatures.cpp
diff --git a/perffeatures.h b/app/perffeatures.h
index c63bea2..c63bea2 100644
--- a/perffeatures.h
+++ b/app/perffeatures.h
diff --git a/perffilesection.cpp b/app/perffilesection.cpp
index 4a6d3e4..4a6d3e4 100644
--- a/perffilesection.cpp
+++ b/app/perffilesection.cpp
diff --git a/perffilesection.h b/app/perffilesection.h
index b375cef..b375cef 100644
--- a/perffilesection.h
+++ b/app/perffilesection.h
diff --git a/perfheader.cpp b/app/perfheader.cpp
index e2abef0..e2abef0 100644
--- a/perfheader.cpp
+++ b/app/perfheader.cpp
diff --git a/perfheader.h b/app/perfheader.h
index 986a18b..986a18b 100644
--- a/perfheader.h
+++ b/app/perfheader.h
diff --git a/perfregisterinfo.cpp b/app/perfregisterinfo.cpp
index 0703881..0703881 100644
--- a/perfregisterinfo.cpp
+++ b/app/perfregisterinfo.cpp
diff --git a/perfregisterinfo.h b/app/perfregisterinfo.h
index c834694..c834694 100644
--- a/perfregisterinfo.h
+++ b/app/perfregisterinfo.h
diff --git a/perfstdin.cpp b/app/perfstdin.cpp
index 5a70976..5a70976 100644
--- a/perfstdin.cpp
+++ b/app/perfstdin.cpp
diff --git a/perfstdin.h b/app/perfstdin.h
index 2633c84..2633c84 100644
--- a/perfstdin.h
+++ b/app/perfstdin.h
diff --git a/perfunwind.cpp b/app/perfunwind.cpp
index b526f89..b79a868 100644
--- a/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -21,7 +21,6 @@
#include "perfunwind.h"
#include "perfregisterinfo.h"
-#include <dwarf.h>
#include <bfd.h>
#include <QDir>
diff --git a/perfunwind.h b/app/perfunwind.h
index df981d0..12b627e 100644
--- a/perfunwind.h
+++ b/app/perfunwind.h
@@ -23,7 +23,7 @@
#include "perfdata.h"
#include "perfregisterinfo.h"
-#include <elfutils/libdwfl.h>
+#include <libdwfl.h>
#include <QFileInfo>
#include <QMap>
#include <QHash>
diff --git a/perfparser.pro b/perfparser.pro
index 4e98b45..3151a8c 100644
--- a/perfparser.pro
+++ b/perfparser.pro
@@ -1,38 +1,5 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2014-08-14T10:44:20
-#
-#-------------------------------------------------
+TEMPLATE = subdirs
-QT += core network
+SUBDIRS = app 3rdparty/elfutils
-QT -= gui
-
-LIBS += -ldw -lbfd
-
-TARGET = perfparser
-CONFIG += console c++11
-CONFIG -= app_bundle
-
-TEMPLATE = app
-
-
-SOURCES += main.cpp \
- perfattributes.cpp \
- perfheader.cpp \
- perffilesection.cpp \
- perffeatures.cpp \
- perfdata.cpp \
- perfunwind.cpp \
- perfregisterinfo.cpp \
- perfstdin.cpp
-
-HEADERS += \
- perfattributes.h \
- perfheader.h \
- perffilesection.h \
- perffeatures.h \
- perfdata.h \
- perfunwind.h \
- perfregisterinfo.h \
- perfstdin.h
+app.depends = 3rdparty/elfutils