summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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