summaryrefslogtreecommitdiffstats
path: root/contrib/elftoolchain
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2016-02-12 20:54:02 +0000
committeremaste <emaste@FreeBSD.org>2016-02-12 20:54:02 +0000
commita6ae90983efabb9784f1e105ffb29eaec3c0573c (patch)
treecd8537a698afe8dd30dc9c4d04c193e5b3b2e94f /contrib/elftoolchain
parent0309ab8781484f9cf0561cbbc3cab6df7139d629 (diff)
parent85217dee0e24c5f3ac285420e843063b4b52c1a0 (diff)
downloadFreeBSD-src-a6ae90983efabb9784f1e105ffb29eaec3c0573c.zip
FreeBSD-src-a6ae90983efabb9784f1e105ffb29eaec3c0573c.tar.gz
Update ELF Tool Chain to upstream rev 3400
Some notable improvements include: readelf: - Add AArch64 relocation definitions. - Report value of unknown relocation types. elfcopy: - Consider symbols with STB_GNU_UNIQUE binding as global symbols. - Fixed support for VMA adjustment for loadable sections found in relocatable objects. - Handle nameless global symbols. - Improve wildcard matching for !-prefixed symbols. - Add PE/COFF support. elfdump: - Improve section type reporting. - Add MIPS-specific section types. This update also includes a significant number of bug fixes. PR: 207091 [exp-run] Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib/elftoolchain')
-rw-r--r--contrib/elftoolchain/addr2line/addr2line.c8
-rw-r--r--contrib/elftoolchain/addr2line/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/ar/ar.c4
-rw-r--r--contrib/elftoolchain/brandelf/brandelf.c4
-rw-r--r--contrib/elftoolchain/common/elfdefinitions.h139
-rwxr-xr-xcontrib/elftoolchain/common/native-elf-format4
-rw-r--r--contrib/elftoolchain/cxxfilt/cxxfilt.c21
-rw-r--r--contrib/elftoolchain/elfcopy/Makefile23
-rw-r--r--contrib/elftoolchain/elfcopy/archive.c6
-rw-r--r--contrib/elftoolchain/elfcopy/elfcopy.119
-rw-r--r--contrib/elftoolchain/elfcopy/elfcopy.h3
-rw-r--r--contrib/elftoolchain/elfcopy/main.c20
-rw-r--r--contrib/elftoolchain/elfcopy/pe.c233
-rw-r--r--contrib/elftoolchain/elfcopy/sections.c107
-rw-r--r--contrib/elftoolchain/elfcopy/segments.c18
-rw-r--r--contrib/elftoolchain/elfcopy/symbols.c126
-rw-r--r--contrib/elftoolchain/elfdump/elfdump.c370
-rw-r--r--contrib/elftoolchain/elfdump/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/libdwarf/_libdwarf.h10
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf.36
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_str.c8
-rw-r--r--contrib/elftoolchain/libdwarf/libdwarf.h4
-rw-r--r--contrib/elftoolchain/libdwarf/libdwarf_rw.c14
-rw-r--r--contrib/elftoolchain/libdwarf/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/libelf/_libelf_config.h2
-rw-r--r--contrib/elftoolchain/libelftc/Makefile13
-rw-r--r--contrib/elftoolchain/libelftc/elftc_bfd_find_target.310
-rw-r--r--contrib/elftoolchain/libelftc/elftc_copyfile.c24
-rw-r--r--contrib/elftoolchain/libelftc/elftc_demangle.c10
-rw-r--r--contrib/elftoolchain/libelftc/elftc_symbol_table_create.3529
-rw-r--r--contrib/elftoolchain/libelftc/libelftc.h6
-rw-r--r--contrib/elftoolchain/libelftc/libelftc_bfdtarget.c26
-rw-r--r--contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c22
-rwxr-xr-xcontrib/elftoolchain/libelftc/make-toolchain-version4
-rw-r--r--contrib/elftoolchain/libelftc/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/libpe/Makefile32
-rw-r--r--contrib/elftoolchain/libpe/_libpe.h213
-rw-r--r--contrib/elftoolchain/libpe/libpe.h121
-rw-r--r--contrib/elftoolchain/libpe/libpe_buffer.c185
-rw-r--r--contrib/elftoolchain/libpe/libpe_coff.c535
-rw-r--r--contrib/elftoolchain/libpe/libpe_dos.c403
-rw-r--r--contrib/elftoolchain/libpe/libpe_init.c145
-rw-r--r--contrib/elftoolchain/libpe/libpe_rich.c128
-rw-r--r--contrib/elftoolchain/libpe/libpe_section.c518
-rw-r--r--contrib/elftoolchain/libpe/libpe_utils.c69
-rw-r--r--contrib/elftoolchain/libpe/os.Linux.mk6
-rw-r--r--contrib/elftoolchain/libpe/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/libpe/pe.h292
-rw-r--r--contrib/elftoolchain/libpe/pe_buffer.c100
-rw-r--r--contrib/elftoolchain/libpe/pe_cntl.c62
-rw-r--r--contrib/elftoolchain/libpe/pe_coff.c157
-rw-r--r--contrib/elftoolchain/libpe/pe_dos.c119
-rw-r--r--contrib/elftoolchain/libpe/pe_flag.c187
-rw-r--r--contrib/elftoolchain/libpe/pe_init.c95
-rw-r--r--contrib/elftoolchain/libpe/pe_rich.c107
-rw-r--r--contrib/elftoolchain/libpe/pe_section.c213
-rw-r--r--contrib/elftoolchain/libpe/pe_symtab.c86
-rw-r--r--contrib/elftoolchain/libpe/pe_update.c86
-rw-r--r--contrib/elftoolchain/nm/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/readelf/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/readelf/readelf.c78
-rw-r--r--contrib/elftoolchain/size/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/strings/os.NetBSD.mk2
-rw-r--r--contrib/elftoolchain/strings/strings.17
-rw-r--r--contrib/elftoolchain/strings/strings.c12
65 files changed, 4894 insertions, 873 deletions
diff --git a/contrib/elftoolchain/addr2line/addr2line.c b/contrib/elftoolchain/addr2line/addr2line.c
index 5310576..3cd8cb5 100644
--- a/contrib/elftoolchain/addr2line/addr2line.c
+++ b/contrib/elftoolchain/addr2line/addr2line.c
@@ -40,7 +40,7 @@
#include "uthash.h"
#include "_elftc.h"
-ELFTC_VCSID("$Id: addr2line.c 3264 2015-11-30 05:38:14Z kaiwang27 $");
+ELFTC_VCSID("$Id: addr2line.c 3273 2015-12-11 21:38:57Z kaiwang27 $");
struct Func {
char *name;
@@ -368,7 +368,8 @@ print_inlines(struct CU *cu, struct Func *f, Dwarf_Unsigned call_file,
printf("%s\n", f->name);
}
}
- (void) printf("%s:%ju\n", base ? basename(file) : file, call_line);
+ (void) printf("%s:%ju\n", base ? basename(file) : file,
+ (uintmax_t) call_line);
if (f->inlined_caller != NULL)
print_inlines(cu, f->inlined_caller, f->call_file,
@@ -562,7 +563,8 @@ out:
}
}
- (void) printf("%s:%ju\n", base ? basename(file) : file, lineno);
+ (void) printf("%s:%ju\n", base ? basename(file) : file,
+ (uintmax_t) lineno);
if (ret == DW_DLV_OK && inlines && cu != NULL &&
cu->srcfiles != NULL && f != NULL && f->inlined_caller != NULL)
diff --git a/contrib/elftoolchain/addr2line/os.NetBSD.mk b/contrib/elftoolchain/addr2line/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/addr2line/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/ar/ar.c b/contrib/elftoolchain/ar/ar.c
index 62f0e55..1b60a12 100644
--- a/contrib/elftoolchain/ar/ar.c
+++ b/contrib/elftoolchain/ar/ar.c
@@ -72,7 +72,7 @@
#include "ar.h"
-ELFTC_VCSID("$Id: ar.c 3243 2015-08-31 19:28:45Z emaste $");
+ELFTC_VCSID("$Id: ar.c 3319 2016-01-13 21:37:53Z jkoshy $");
enum options
{
@@ -407,7 +407,7 @@ Usage: %s <command> [options] archive file...\n\
-F FORMAT | --flavor=FORMAT\n\
Create archives with the specified format.\n\
-S Do not generate an archive symbol table.\n\
- -U Use original metadata, for unique archive checksums.\n"
+ -U Use original metadata for archive members.\n"
static void
bsdar_usage(void)
diff --git a/contrib/elftoolchain/brandelf/brandelf.c b/contrib/elftoolchain/brandelf/brandelf.c
index cbe5d6c..22166f7 100644
--- a/contrib/elftoolchain/brandelf/brandelf.c
+++ b/contrib/elftoolchain/brandelf/brandelf.c
@@ -44,7 +44,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: brandelf.c 3234 2015-07-31 12:35:09Z emaste $");
+ELFTC_VCSID("$Id: brandelf.c 3354 2016-01-18 21:50:15Z jkoshy $");
static int elftype(const char *);
static const char *iselftype(int);
@@ -212,7 +212,7 @@ main(int argc, char **argv)
/*
* Update the ABI type.
*/
- ehdr.e_ident[EI_OSABI] = type;
+ ehdr.e_ident[EI_OSABI] = (unsigned char) type;
if (gelf_update_ehdr(elf, &ehdr) == 0) {
warnx("gelf_update_ehdr error: %s",
elf_errmsg(-1));
diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h
index e953c92..fa6132d 100644
--- a/contrib/elftoolchain/common/elfdefinitions.h
+++ b/contrib/elftoolchain/common/elfdefinitions.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: elfdefinitions.h 3253 2015-10-10 18:31:33Z kaiwang27 $
+ * $Id: elfdefinitions.h 3392 2016-02-05 19:51:22Z emaste $
*/
/*
@@ -1228,6 +1228,7 @@ _ELF_DEFINE_STB(STB_GLOBAL, 1, \
_ELF_DEFINE_STB(STB_WEAK, 2, \
"visible across all object files but with low precedence") \
_ELF_DEFINE_STB(STB_LOOS, 10, "start of OS-specific range") \
+_ELF_DEFINE_STB(STB_GNU_UNIQUE, 10, "unique symbol (GNU)") \
_ELF_DEFINE_STB(STB_HIOS, 12, "end of OS-specific range") \
_ELF_DEFINE_STB(STB_LOPROC, 13, \
"start of processor-specific range") \
@@ -1259,6 +1260,7 @@ _ELF_DEFINE_STT(STT_LOPROC, 13, \
"start of processor-specific types") \
_ELF_DEFINE_STT(STT_ARM_TFUNC, 13, "Thumb function (GNU)") \
_ELF_DEFINE_STT(STT_ARM_16BIT, 15, "Thumb label (GNU)") \
+_ELF_DEFINE_STT(STT_SPARC_REGISTER, 13, "SPARC register information") \
_ELF_DEFINE_STT(STT_HIPROC, 15, \
"end of processor-specific types")
@@ -1395,7 +1397,7 @@ _ELF_DEFINE_RELOC(R_386_GOT32, 3) \
_ELF_DEFINE_RELOC(R_386_PLT32, 4) \
_ELF_DEFINE_RELOC(R_386_COPY, 5) \
_ELF_DEFINE_RELOC(R_386_GLOB_DAT, 6) \
-_ELF_DEFINE_RELOC(R_386_JMP_SLOT, 7) \
+_ELF_DEFINE_RELOC(R_386_JUMP_SLOT, 7) \
_ELF_DEFINE_RELOC(R_386_RELATIVE, 8) \
_ELF_DEFINE_RELOC(R_386_GOTOFF, 9) \
_ELF_DEFINE_RELOC(R_386_GOTPC, 10) \
@@ -1407,9 +1409,129 @@ _ELF_DEFINE_RELOC(R_386_PC8, 23)
/*
*/
-#define _ELF_DEFINE_AARCH64_RELOCATIONS() \
-_ELF_DEFINE_RELOC(R_AARCH64_ABS64, 257) \
-_ELF_DEFINE_RELOC(R_AARCH64_ABS32, 258) \
+#define _ELF_DEFINE_AARCH64_RELOCATIONS() \
+_ELF_DEFINE_RELOC(R_AARCH64_NONE, 0) \
+_ELF_DEFINE_RELOC(R_AARCH64_ABS64, 257) \
+_ELF_DEFINE_RELOC(R_AARCH64_ABS32, 258) \
+_ELF_DEFINE_RELOC(R_AARCH64_ABS16, 259) \
+_ELF_DEFINE_RELOC(R_AARCH64_PREL64, 260) \
+_ELF_DEFINE_RELOC(R_AARCH64_PREL32, 261) \
+_ELF_DEFINE_RELOC(R_AARCH64_PREL16, 262) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G0, 263) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G0_NC, 264) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G1, 265) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G1_NC, 266) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G2, 267) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G2_NC, 268) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G3, 269) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G0, 270) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G1, 271) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G2, 272) \
+_ELF_DEFINE_RELOC(R_AARCH64_LD_PREL_LO19, 273) \
+_ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_LO21, 274) \
+_ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_PG_HI21, 275) \
+_ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_PG_HI21_NC, 276) \
+_ELF_DEFINE_RELOC(R_AARCH64_ADD_ABS_LO12_NC, 277) \
+_ELF_DEFINE_RELOC(R_AARCH64_LDST8_ABS_LO12_NC, 278) \
+_ELF_DEFINE_RELOC(R_AARCH64_TSTBR14, 279) \
+_ELF_DEFINE_RELOC(R_AARCH64_CONDBR19, 280) \
+_ELF_DEFINE_RELOC(R_AARCH64_JUMP26, 282) \
+_ELF_DEFINE_RELOC(R_AARCH64_CALL26, 283) \
+_ELF_DEFINE_RELOC(R_AARCH64_LDST16_ABS_LO12_NC, 284) \
+_ELF_DEFINE_RELOC(R_AARCH64_LDST32_ABS_LO12_NC, 285) \
+_ELF_DEFINE_RELOC(R_AARCH64_LDST64_ABS_LO12_NC, 286) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G0, 287) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G0_NC, 288) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G1, 289) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G1_NC, 290) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G2, 291) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G2_NC, 292) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G3, 293) \
+_ELF_DEFINE_RELOC(R_AARCH64_LDST128_ABS_LO12_NC, 299) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G0, 300) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G0_NC, 301) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G1, 302) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G1_NC, 303) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G2, 304) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G2_NC, 305) \
+_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G3, 306) \
+_ELF_DEFINE_RELOC(R_AARCH64_GOTREL64, 307) \
+_ELF_DEFINE_RELOC(R_AARCH64_GOTREL32, 308) \
+_ELF_DEFINE_RELOC(R_AARCH64_GOT_LD_PREL19, 309) \
+_ELF_DEFINE_RELOC(R_AARCH64_LD64_GOTOFF_LO15, 310) \
+_ELF_DEFINE_RELOC(R_AARCH64_ADR_GOT_PAGE, 311) \
+_ELF_DEFINE_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 312) \
+_ELF_DEFINE_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 313) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 512) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 513) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 514) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_MOVW_G1, 515) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_MOVW_G0_NC, 516) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADR_PREL21, 517) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADR_PAGE21, 518) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_LO12_NC, 519) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_G1, 520) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_G0_NC, 521) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LD_PREL19, 522) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G2, 523) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1, 524) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, 525) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0, 526) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, 527) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_HI12, 529) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, 530) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12, 531) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, 532) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12, 533) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, 534) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12, 535) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, 536) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12, 537) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, 538) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1, 539) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, 540) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, 541) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, 542) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, 543) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G2, 544) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1, 545) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC, 546) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0, 547) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC, 548) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_HI12, 549) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12, 550) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC, 551) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12, 552) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, 553) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12, 554) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, 555) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12, 556) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, 557) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12, 558) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 559) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LD_PREL19, 560) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADR_PREL21, 561) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21, 562) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LD64_LO12, 563) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADD_LO12, 564) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_OFF_G1, 565) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC, 566) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LDR, 567) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADD, 568) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_CALL, 569) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 570) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 571) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 572) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 573) \
+_ELF_DEFINE_RELOC(R_AARCH64_COPY, 1024) \
+_ELF_DEFINE_RELOC(R_AARCH64_GLOB_DAT, 1025) \
+_ELF_DEFINE_RELOC(R_AARCH64_JUMP_SLOT, 1026) \
+_ELF_DEFINE_RELOC(R_AARCH64_RELATIVE, 1027) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLS_DTPREL64, 1028) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLS_DTPMOD64, 1029) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLS_TPREL64, 1030) \
+_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC, 1031) \
+_ELF_DEFINE_RELOC(R_AARCH64_IRELATIVE, 1032)
/*
* These are the symbols used in the Sun ``Linkers and Loaders
@@ -1633,7 +1755,7 @@ _ELF_DEFINE_RELOC(R_IA_64_LTV32MSB, 0x74) \
_ELF_DEFINE_RELOC(R_IA_64_LTV32LSB, 0x75) \
_ELF_DEFINE_RELOC(R_IA_64_LTV64MSB, 0x76) \
_ELF_DEFINE_RELOC(R_IA_64_LTV64LSB, 0x77) \
-_ELF_DEFINE_RELOC(R_IA_64_PCREL21BIa, 0x79) \
+_ELF_DEFINE_RELOC(R_IA_64_PCREL21BI, 0x79) \
_ELF_DEFINE_RELOC(R_IA_64_PCREL22, 0x7A) \
_ELF_DEFINE_RELOC(R_IA_64_PCREL64I, 0x7B) \
_ELF_DEFINE_RELOC(R_IA_64_IPLTMSB, 0x80) \
@@ -1723,7 +1845,7 @@ _ELF_DEFINE_RELOC(R_PPC_REL32, 26) \
_ELF_DEFINE_RELOC(R_PPC_PLT32, 27) \
_ELF_DEFINE_RELOC(R_PPC_PLTREL32, 28) \
_ELF_DEFINE_RELOC(R_PPC_PLT16_LO, 29) \
-_ELF_DEFINE_RELOC(R_PPL_PLT16_HI, 30) \
+_ELF_DEFINE_RELOC(R_PPC_PLT16_HI, 30) \
_ELF_DEFINE_RELOC(R_PPC_PLT16_HA, 31) \
_ELF_DEFINE_RELOC(R_PPC_SDAREL16, 32) \
_ELF_DEFINE_RELOC(R_PPC_SECTOFF, 33) \
@@ -1926,7 +2048,7 @@ _ELF_DEFINE_RELOC(R_RISCV_SUB32, 39) \
_ELF_DEFINE_RELOC(R_RISCV_SUB64, 40) \
_ELF_DEFINE_RELOC(R_RISCV_GNU_VTINHERIT, 41) \
_ELF_DEFINE_RELOC(R_RISCV_GNU_VTENTRY, 42) \
-_ELF_DEFINE_RELOC(R_RISCV_ALIGN 43) \
+_ELF_DEFINE_RELOC(R_RISCV_ALIGN, 43) \
_ELF_DEFINE_RELOC(R_RISCV_RVC_BRANCH, 44) \
_ELF_DEFINE_RELOC(R_RISCV_RVC_JUMP, 45)
@@ -2042,6 +2164,7 @@ _ELF_DEFINE_IA64_RELOCATIONS() \
_ELF_DEFINE_MIPS_RELOCATIONS() \
_ELF_DEFINE_PPC32_RELOCATIONS() \
_ELF_DEFINE_PPC64_RELOCATIONS() \
+_ELF_DEFINE_RISCV_RELOCATIONS() \
_ELF_DEFINE_SPARC_RELOCATIONS() \
_ELF_DEFINE_X86_64_RELOCATIONS()
diff --git a/contrib/elftoolchain/common/native-elf-format b/contrib/elftoolchain/common/native-elf-format
index d36ab53..2bdd914 100755
--- a/contrib/elftoolchain/common/native-elf-format
+++ b/contrib/elftoolchain/common/native-elf-format
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# $Id: native-elf-format 3186 2015-04-16 22:16:40Z emaste $
+# $Id: native-elf-format 3293 2016-01-07 19:26:27Z emaste $
#
# Find the native ELF format for a host platform by compiling a
# test object and examining the resulting object.
@@ -33,6 +33,8 @@ $1 ~ "Data:" {
$1 ~ "Machine:" {
if (match($0, "Intel.*386")) {
elfarch = "EM_386";
+ } else if (match($0, "MIPS")) {
+ elfarch = "EM_MIPS";
} else if (match($0, ".*[xX]86-64")) {
elfarch = "EM_X86_64";
} else {
diff --git a/contrib/elftoolchain/cxxfilt/cxxfilt.c b/contrib/elftoolchain/cxxfilt/cxxfilt.c
index 4efa45b..9318c64 100644
--- a/contrib/elftoolchain/cxxfilt/cxxfilt.c
+++ b/contrib/elftoolchain/cxxfilt/cxxfilt.c
@@ -35,7 +35,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: cxxfilt.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: cxxfilt.c 3356 2016-01-22 22:31:38Z jkoshy $");
#define STRBUFSZ 8192
@@ -112,11 +112,11 @@ find_format(const char *fstr)
}
static char *
-demangle(char *name, int strict, int *pos)
+demangle(char *name, int strict, size_t *pos)
{
static char dem[STRBUFSZ];
char nb[STRBUFSZ];
- int p, t;
+ size_t p, t;
if (stripus && *name == '_') {
strncpy(nb, name + 1, sizeof(nb) - 1);
@@ -128,10 +128,10 @@ demangle(char *name, int strict, int *pos)
nb[sizeof(nb) - 1] = '\0';
p = strlen(nb);
- if (p <= 0)
+ if (p == 0)
return NULL;
- while (elftc_demangle(nb, dem, sizeof(dem), format) < 0) {
+ while (elftc_demangle(nb, dem, sizeof(dem), (unsigned) format) < 0) {
if (!strict && p > 1) {
nb[--p] = '\0';
continue;
@@ -149,7 +149,8 @@ int
main(int argc, char **argv)
{
char *dem, buf[STRBUFSZ];
- int c, i, p, s, opt;
+ size_t i, p, s;
+ int c, n, opt;
while ((opt = getopt_long(argc, argv, "_nps:V", longopts, NULL)) !=
-1) {
@@ -182,9 +183,9 @@ main(int argc, char **argv)
argc -= optind;
if (*argv != NULL) {
- for (i = 0; i < argc; i++) {
- if ((dem = demangle(argv[i], 1, NULL)) == NULL)
- fprintf(stderr, "Failed: %s\n", argv[i]);
+ for (n = 0; n < argc; n++) {
+ if ((dem = demangle(argv[n], 1, NULL)) == NULL)
+ fprintf(stderr, "Failed: %s\n", argv[n]);
else
printf("%s\n", dem);
}
@@ -213,7 +214,7 @@ main(int argc, char **argv)
if ((size_t) p >= sizeof(buf) - 1)
warnx("buffer overflowed");
else
- buf[p++] = c;
+ buf[p++] = (char) c;
}
}
diff --git a/contrib/elftoolchain/elfcopy/Makefile b/contrib/elftoolchain/elfcopy/Makefile
index cb1a31b..8b208e0 100644
--- a/contrib/elftoolchain/elfcopy/Makefile
+++ b/contrib/elftoolchain/elfcopy/Makefile
@@ -1,10 +1,13 @@
-# $Id: Makefile 2290 2011-12-04 07:20:46Z jkoshy $
+# $Id: Makefile 3381 2016-01-30 19:39:47Z jkoshy $
TOP= ..
+.include "${TOP}/mk/elftoolchain.components.mk"
+
PROG= elfcopy
-SRCS= archive.c ascii.c binary.c main.c sections.c segments.c symbols.c
+SRCS= archive.c ascii.c binary.c main.c sections.c segments.c \
+ symbols.c
WARNS?= 5
@@ -15,14 +18,24 @@ LDADD= -lelf -lelftc
LDADD+= -larchive
.endif
+.if defined(WITH_PE) && ${WITH_PE:tl} == "yes"
+SRCS+= pe.c
+CFLAGS+= -DWITH_PE=1
+
+DPADD+= ${LIBPE}
+LDADD+= -lpe
+.endif
+
MAN= elfcopy.1 mcs.1 strip.1
+MLINKS= elfcopy.1 objcopy.1
NO_SHARED?= yes
-LINKS= ${BINDIR}/elfcopy ${BINDIR}/strip \
- ${BINDIR}/elfcopy ${BINDIR}/mcs
+LINKS= ${BINDIR}/elfcopy ${BINDIR}/mcs \
+ ${BINDIR}/elfcopy ${BINDIR}/objcopy \
+ ${BINDIR}/elfcopy ${BINDIR}/strip
-EXTRA_TARGETS= strip mcs
+EXTRA_TARGETS= mcs strip objcopy
CLEANFILES+= ${EXTRA_TARGETS}
diff --git a/contrib/elftoolchain/elfcopy/archive.c b/contrib/elftoolchain/elfcopy/archive.c
index 682a1df..97e2498 100644
--- a/contrib/elftoolchain/elfcopy/archive.c
+++ b/contrib/elftoolchain/elfcopy/archive.c
@@ -38,7 +38,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: archive.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: archive.c 3287 2015-12-31 16:58:48Z emaste $");
#define _ARMAG_LEN 8 /* length of ar magic string */
#define _ARHDR_LEN 60 /* length of ar header */
@@ -382,7 +382,7 @@ ac_read_objs(struct elfcopy *ecp, int ifd)
if (lseek(ifd, 0, SEEK_SET) == -1)
err(EXIT_FAILURE, "lseek failed");
if ((a = archive_read_new()) == NULL)
- errx(EXIT_FAILURE, "%s", archive_error_string(a));
+ errx(EXIT_FAILURE, "archive_read_new failed");
archive_read_support_format_ar(a);
AC(archive_read_open_fd(a, ifd, 10240));
for(;;) {
@@ -443,7 +443,7 @@ ac_write_objs(struct elfcopy *ecp, int ofd)
int nr;
if ((a = archive_write_new()) == NULL)
- errx(EXIT_FAILURE, "%s", archive_error_string(a));
+ errx(EXIT_FAILURE, "archive_write_new failed");
archive_write_set_format_ar_svr4(a);
AC(archive_write_open_fd(a, ofd));
diff --git a/contrib/elftoolchain/elfcopy/elfcopy.1 b/contrib/elftoolchain/elfcopy/elfcopy.1
index 83cda5d..b7b0ce4 100644
--- a/contrib/elftoolchain/elfcopy/elfcopy.1
+++ b/contrib/elftoolchain/elfcopy/elfcopy.1
@@ -21,13 +21,14 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elfcopy.1 3266 2015-12-07 15:38:26Z emaste $
+.\" $Id: elfcopy.1 3381 2016-01-30 19:39:47Z jkoshy $
.\"
-.Dd December 7, 2015
+.Dd January 29, 2016
.Os
.Dt ELFCOPY 1
.Sh NAME
-.Nm elfcopy
+.Nm elfcopy ,
+.Nm objcopy
.Nd copy and translate object files
.Sh SYNOPSIS
.Nm
@@ -85,7 +86,7 @@
.Sh DESCRIPTION
The
.Nm
-utility copies the content of the ELF object named by argument
+utility copies the content of the binary object named by argument
.Ar infile
to that named by argument
.Ar outfile ,
@@ -121,6 +122,10 @@ to the output.
.It Fl O Ar objformat | Fl -output-target= Ns Ar objformat
Write the output file using the object format specified in argument
.Ar objformat .
+The argument
+.Ar objformat
+should be one of the target names recognized by
+.Xr elftc_bfd_find_target 3 .
.It Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname
Remove any section with name
.Ar sectionname
@@ -330,8 +335,14 @@ Do not copy symbols that are not needed for relocation processing.
.Xr mcs 1 ,
.Xr strip 1 ,
.Xr elf 3 ,
+.Xr elftc_bfd_find_target 3 ,
.Xr ar 5 ,
.Xr elf 5
+.Sh COMPATIBILITY
+The
+.Nm
+utility is expected to be option compatible with GNU
+.Nm objcopy .
.Sh HISTORY
.Nm
has been implemented by
diff --git a/contrib/elftoolchain/elfcopy/elfcopy.h b/contrib/elftoolchain/elfcopy/elfcopy.h
index 48574b5..614c0e7 100644
--- a/contrib/elftoolchain/elfcopy/elfcopy.h
+++ b/contrib/elftoolchain/elfcopy/elfcopy.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: elfcopy.h 3221 2015-05-24 23:42:43Z kaiwang27 $
+ * $Id: elfcopy.h 3310 2016-01-10 09:10:54Z kaiwang27 $
*/
#include <sys/queue.h>
@@ -287,6 +287,7 @@ struct section *create_external_section(struct elfcopy *_ecp, const char *_name,
int _loadable);
void create_external_symtab(struct elfcopy *_ecp);
void create_ihex(int _ifd, int _ofd);
+void create_pe(struct elfcopy *_ecp, int _ifd, int _ofd);
void create_scn(struct elfcopy *_ecp);
void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn);
void create_symtab(struct elfcopy *_ecp);
diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c
index e2685b4..b51ba4e 100644
--- a/contrib/elftoolchain/elfcopy/main.c
+++ b/contrib/elftoolchain/elfcopy/main.c
@@ -39,7 +39,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: main.c 3268 2015-12-07 20:30:55Z emaste $");
+ELFTC_VCSID("$Id: main.c 3399 2016-02-12 18:07:56Z emaste $");
enum options
{
@@ -316,6 +316,7 @@ create_elf(struct elfcopy *ecp)
oeh.e_entry = ieh.e_entry;
oeh.e_version = ieh.e_version;
+ ecp->flags &= ~(EXECUTABLE | DYNAMIC | RELOCATABLE);
if (ieh.e_type == ET_EXEC)
ecp->flags |= EXECUTABLE;
else if (ieh.e_type == ET_DYN)
@@ -722,6 +723,15 @@ create_file(struct elfcopy *ecp, const char *src, const char *dst)
create_srec(ecp, ofd, ofd0,
dst != NULL ? dst : src);
break;
+ case ETF_PE:
+ case ETF_EFI:
+#if WITH_PE
+ create_pe(ecp, ofd, ofd0);
+#else
+ errx(EXIT_FAILURE, "PE/EFI support not enabled"
+ " at compile time");
+#endif
+ break;
default:
errx(EXIT_FAILURE, "Internal: unsupported"
" output flavour %d", ecp->oec);
@@ -1345,6 +1355,9 @@ set_output_target(struct elfcopy *ecp, const char *target_name)
ecp->oed = elftc_bfd_target_byteorder(tgt);
ecp->oem = elftc_bfd_target_machine(tgt);
}
+ if (ecp->otf == ETF_EFI || ecp->otf == ETF_PE)
+ ecp->oem = elftc_bfd_target_machine(tgt);
+
ecp->otgt = target_name;
}
@@ -1366,7 +1379,7 @@ set_osabi(struct elfcopy *ecp, const char *abi)
#define ELFCOPY_USAGE_MESSAGE "\
Usage: %s [options] infile [outfile]\n\
- Transform an ELF object.\n\n\
+ Transform object files.\n\n\
Options:\n\
-d | -g | --strip-debug Remove debugging information from the output.\n\
-j SECTION | --only-section=SECTION\n\
@@ -1382,6 +1395,8 @@ Usage: %s [options] infile [outfile]\n\
-N SYM | --strip-symbol=SYM Do not copy symbol SYM to the output.\n\
-O FORMAT | --output-target=FORMAT\n\
Specify object format for the output file.\n\
+ FORMAT should be a target name understood by\n\
+ elftc_bfd_find_target(3).\n\
-R NAME | --remove-section=NAME\n\
Remove the named section.\n\
-S | --strip-all Remove all symbol and relocation information\n\
@@ -1471,6 +1486,7 @@ Usage: %s [options] file...\n\
Options:\n\
-d | -g | -S | --strip-debug Remove debugging symbols.\n\
-h | --help Print a help message.\n\
+ -o FILE | --output-file FILE Write output to FILE.\n\
--only-keep-debug Keep debugging information only.\n\
-p | --preserve-dates Preserve access and modification times.\n\
-s | --strip-all Remove all symbols.\n\
diff --git a/contrib/elftoolchain/elfcopy/pe.c b/contrib/elftoolchain/elfcopy/pe.c
new file mode 100644
index 0000000..0d075c5
--- /dev/null
+++ b/contrib/elftoolchain/elfcopy/pe.c
@@ -0,0 +1,233 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <err.h>
+#include <gelf.h>
+#include <libpe.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "elfcopy.h"
+
+ELFTC_VCSID("$Id: pe.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+/* Convert ELF object to Portable Executable (PE). */
+void
+create_pe(struct elfcopy *ecp, int ifd, int ofd)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ GElf_Ehdr eh;
+ GElf_Shdr sh;
+ PE *pe;
+ PE_Scn *ps;
+ PE_SecHdr psh;
+ PE_CoffHdr pch;
+ PE_OptHdr poh;
+ PE_Object po;
+ PE_Buffer *pb;
+ const char *name;
+ size_t indx;
+ int elferr, i;
+
+ if (ecp->otf == ETF_EFI || ecp->oem == EM_X86_64)
+ po = PE_O_PE32P;
+ else
+ po = PE_O_PE32;
+
+ if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL)
+ errx(EXIT_FAILURE, "elf_begin() failed: %s",
+ elf_errmsg(-1));
+
+ if (gelf_getehdr(e, &eh) == NULL)
+ errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
+ elf_errmsg(-1));
+
+ if (elf_getshstrndx(ecp->ein, &indx) == 0)
+ errx(EXIT_FAILURE, "elf_getshstrndx() failed: %s",
+ elf_errmsg(-1));
+
+ if ((pe = pe_init(ofd, PE_C_WRITE, po)) == NULL)
+ err(EXIT_FAILURE, "pe_init() failed");
+
+ /* Setup PE COFF header. */
+ memset(&pch, 0, sizeof(pch));
+ switch (ecp->oem) {
+ case EM_386:
+ pch.ch_machine = IMAGE_FILE_MACHINE_I386;
+ break;
+ case EM_X86_64:
+ pch.ch_machine = IMAGE_FILE_MACHINE_AMD64;
+ break;
+ default:
+ pch.ch_machine = IMAGE_FILE_MACHINE_UNKNOWN;
+ break;
+ }
+ pch.ch_timestamp = (uint32_t) time(NULL);
+ if (pe_update_coff_header(pe, &pch) < 0)
+ err(EXIT_FAILURE, "pe_update_coff_header() failed");
+
+ /* Setup PE optional header. */
+ memset(&poh, 0, sizeof(poh));
+ if (ecp->otf == ETF_EFI)
+ poh.oh_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
+ poh.oh_entry = (uint32_t) eh.e_entry;
+
+ /*
+ * Default section alignment and file alignment. (Here the
+ * section alignment is set to the default page size of the
+ * archs supported. We should use different section alignment
+ * for some arch. (e.g. IA64)
+ */
+ poh.oh_secalign = 0x1000;
+ poh.oh_filealign = 0x200;
+
+ /* Copy sections. */
+ scn = NULL;
+ while ((scn = elf_nextscn(e, scn)) != NULL) {
+
+ /*
+ * Read in ELF section.
+ */
+
+ if (gelf_getshdr(scn, &sh) == NULL) {
+ warnx("gelf_getshdr() failed: %s", elf_errmsg(-1));
+ (void) elf_errno();
+ continue;
+ }
+ if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) ==
+ NULL) {
+ warnx("elf_strptr() failed: %s", elf_errmsg(-1));
+ (void) elf_errno();
+ continue;
+ }
+
+ /* Skip sections unneeded. */
+ if (strcmp(name, ".shstrtab") == 0 ||
+ strcmp(name, ".symtab") == 0 ||
+ strcmp(name, ".strtab") == 0)
+ continue;
+
+ if ((d = elf_getdata(scn, NULL)) == NULL) {
+ warnx("elf_getdata() failed: %s", elf_errmsg(-1));
+ (void) elf_errno();
+ continue;
+ }
+
+ if (strcmp(name, ".text") == 0) {
+ poh.oh_textbase = (uint32_t) sh.sh_addr;
+ poh.oh_textsize = (uint32_t) roundup(sh.sh_size,
+ poh.oh_filealign);
+ } else {
+ if (po == PE_O_PE32 && strcmp(name, ".data") == 0)
+ poh.oh_database = sh.sh_addr;
+ if (sh.sh_type == SHT_NOBITS)
+ poh.oh_bsssize += (uint32_t)
+ roundup(sh.sh_size, poh.oh_filealign);
+ else if (sh.sh_flags & SHF_ALLOC)
+ poh.oh_datasize += (uint32_t)
+ roundup(sh.sh_size, poh.oh_filealign);
+ }
+
+ /*
+ * Create PE/COFF section.
+ */
+
+ if ((ps = pe_newscn(pe)) == NULL) {
+ warn("pe_newscn() failed");
+ continue;
+ }
+
+ /*
+ * Setup PE/COFF section header. The section name is not
+ * NUL-terminated if its length happens to be 8. Long
+ * section name should be truncated for PE image according
+ * to the PE/COFF specification.
+ */
+ memset(&psh, 0, sizeof(psh));
+ strncpy(psh.sh_name, name, sizeof(psh.sh_name));
+ psh.sh_addr = sh.sh_addr;
+ psh.sh_virtsize = sh.sh_size;
+ if (sh.sh_type != SHT_NOBITS)
+ psh.sh_rawsize = sh.sh_size;
+ else
+ psh.sh_char |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+
+ /*
+ * Translate ELF section flags to PE/COFF section flags.
+ */
+ psh.sh_char |= IMAGE_SCN_MEM_READ;
+ if (sh.sh_flags & SHF_WRITE)
+ psh.sh_char |= IMAGE_SCN_MEM_WRITE;
+ if (sh.sh_flags & SHF_EXECINSTR)
+ psh.sh_char |= IMAGE_SCN_MEM_EXECUTE |
+ IMAGE_SCN_CNT_CODE;
+ if ((sh.sh_flags & SHF_ALLOC) && (psh.sh_char & 0xF0) == 0)
+ psh.sh_char |= IMAGE_SCN_CNT_INITIALIZED_DATA;
+ for (i = 0xE; i > 0; i--) {
+ if (sh.sh_addralign & (1U << (i - 1))) {
+ psh.sh_char |= i << 20;
+ break;
+ }
+ }
+
+ /* Mark relocation section "discardable". */
+ if (strcmp(name, ".reloc") == 0)
+ psh.sh_char |= IMAGE_SCN_MEM_DISCARDABLE;
+
+ if (pe_update_section_header(ps, &psh) < 0) {
+ warn("pe_update_section_header() failed");
+ continue;
+ }
+
+ /* Copy section content. */
+ if ((pb = pe_newbuffer(ps)) == NULL) {
+ warn("pe_newbuffer() failed");
+ continue;
+ }
+ pb->pb_align = 1;
+ pb->pb_off = 0;
+ pb->pb_size = sh.sh_size;
+ pb->pb_buf = d->d_buf;
+ }
+ elferr = elf_errno();
+ if (elferr != 0)
+ warnx("elf_nextscn() failed: %s", elf_errmsg(elferr));
+
+ /* Update PE optional header. */
+ if (pe_update_opt_header(pe, &poh) < 0)
+ err(EXIT_FAILURE, "pe_update_opt_header() failed");
+
+ /* Write out PE/COFF object. */
+ if (pe_update(pe) < 0)
+ err(EXIT_FAILURE, "pe_update() failed");
+
+ pe_finish(pe);
+ elf_end(e);
+}
diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c
index a17c9ab..2ba3d48 100644
--- a/contrib/elftoolchain/elfcopy/sections.c
+++ b/contrib/elftoolchain/elfcopy/sections.c
@@ -34,7 +34,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: sections.c 3272 2015-12-11 20:00:54Z kaiwang27 $");
+ELFTC_VCSID("$Id: sections.c 3346 2016-01-17 20:09:15Z kaiwang27 $");
static void add_gnu_debuglink(struct elfcopy *ecp);
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
@@ -223,6 +223,7 @@ static int
is_debug_section(const char *name)
{
const char *dbg_sec[] = {
+ ".apple_",
".debug",
".gnu.linkonce.wi.",
".line",
@@ -369,7 +370,7 @@ create_scn(struct elfcopy *ecp)
is = NULL;
while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
if (gelf_getshdr(is, &ish) == NULL)
- errx(EXIT_FAILURE, "219 gelf_getshdr failed: %s",
+ errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
elf_errmsg(-1));
if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL)
errx(EXIT_FAILURE, "elf_strptr failed: %s",
@@ -416,12 +417,19 @@ create_scn(struct elfcopy *ecp)
* is loadable, but if user explicitly set section flags
* while neither "load" nor "alloc" is set, we make the
* section unloadable.
+ *
+ * Sections in relocatable object is loadable if
+ * section flag SHF_ALLOC is set.
*/
if (sec_flags &&
(sec_flags & (SF_LOAD | SF_ALLOC)) == 0)
s->loadable = 0;
- else
+ else {
s->loadable = add_to_inseg_list(ecp, s);
+ if ((ecp->flags & RELOCATABLE) &&
+ (ish.sh_flags & SHF_ALLOC))
+ s->loadable = 1;
+ }
} else {
/* Assuming .shstrtab is "unloadable". */
s = ecp->shstrtab;
@@ -875,10 +883,10 @@ resync_sections(struct elfcopy *ecp)
if (s->align == 0)
s->align = 1;
if (off <= s->off) {
- if (!s->loadable)
+ if (!s->loadable || (ecp->flags & RELOCATABLE))
s->off = roundup(off, s->align);
} else {
- if (s->loadable)
+ if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
warnx("moving loadable section %s, "
"is this intentional?", s->name);
s->off = roundup(off, s->align);
@@ -1028,8 +1036,11 @@ print_section(struct section *s)
print_data(s->buf, s->sz);
} else {
id = NULL;
- while ((id = elf_getdata(s->is, id)) != NULL)
+ while ((id = elf_getdata(s->is, id)) != NULL ||
+ (id = elf_rawdata(s->is, id)) != NULL) {
+ (void) elf_errno();
print_data(id->d_buf, id->d_size);
+ }
elferr = elf_errno();
if (elferr != 0)
errx(EXIT_FAILURE, "elf_getdata() failed: %s",
@@ -1049,7 +1060,9 @@ read_section(struct section *s, size_t *size)
sz = 0;
b = NULL;
id = NULL;
- while ((id = elf_getdata(s->is, id)) != NULL) {
+ while ((id = elf_getdata(s->is, id)) != NULL ||
+ (id = elf_rawdata(s->is, id)) != NULL) {
+ (void) elf_errno();
if (b == NULL)
b = malloc(id->d_size);
else
@@ -1077,10 +1090,10 @@ copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
GElf_Shdr ish, osh;
if (gelf_getshdr(s->is, &ish) == NULL)
- errx(EXIT_FAILURE, "526 gelf_getshdr() failed: %s",
+ errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
elf_errmsg(-1));
if (gelf_getshdr(s->os, &osh) == NULL)
- errx(EXIT_FAILURE, "529 gelf_getshdr() failed: %s",
+ errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
elf_errmsg(-1));
if (copy)
@@ -1097,19 +1110,32 @@ copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
if (sec_flags) {
osh.sh_flags = 0;
- if (sec_flags & SF_ALLOC) {
+ if (sec_flags & SF_ALLOC)
osh.sh_flags |= SHF_ALLOC;
- if (!s->loadable)
- warnx("set SHF_ALLOC flag for "
- "unloadable section %s",
- s->name);
- }
if ((sec_flags & SF_READONLY) == 0)
osh.sh_flags |= SHF_WRITE;
if (sec_flags & SF_CODE)
osh.sh_flags |= SHF_EXECINSTR;
+ if ((sec_flags & SF_CONTENTS) &&
+ s->type == SHT_NOBITS && s->sz > 0) {
+ /*
+ * Convert SHT_NOBITS section to section with
+ * (zero'ed) content on file.
+ */
+ osh.sh_type = s->type = SHT_PROGBITS;
+ if ((s->buf = calloc(1, s->sz)) == NULL)
+ err(EXIT_FAILURE, "malloc failed");
+ s->nocopy = 1;
+ }
} else {
osh.sh_flags = ish.sh_flags;
+ /*
+ * Newer binutils as(1) emits the section flag
+ * SHF_INFO_LINK for relocation sections. elfcopy
+ * emits this flag in the output section if it's
+ * missing in the input section, to remain compatible
+ * with binutils.
+ */
if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
osh.sh_flags |= SHF_INFO_LINK;
}
@@ -1135,11 +1161,14 @@ copy_data(struct section *s)
return;
if ((id = elf_getdata(s->is, NULL)) == NULL) {
- elferr = elf_errno();
- if (elferr != 0)
- errx(EXIT_FAILURE, "elf_getdata() failed: %s",
- elf_errmsg(elferr));
- return;
+ (void) elf_errno();
+ if ((id = elf_rawdata(s->is, NULL)) == NULL) {
+ elferr = elf_errno();
+ if (elferr != 0)
+ errx(EXIT_FAILURE, "failed to read section:"
+ " %s", s->name);
+ return;
+ }
}
if ((od = elf_newdata(s->os)) == NULL)
@@ -1245,6 +1274,7 @@ insert_sections(struct elfcopy *ecp)
struct sec_add *sa;
struct section *s;
size_t off;
+ uint64_t stype;
/* Put these sections in the end of current list. */
off = 0;
@@ -1259,8 +1289,20 @@ insert_sections(struct elfcopy *ecp)
/* TODO: Add section header vma/lma, flag changes here */
+ /*
+ * The default section type for user added section is
+ * SHT_PROGBITS. If the section name match certain patterns,
+ * elfcopy will try to set a more appropriate section type.
+ * However, data type is always set to ELF_T_BYTE and no
+ * translation is performed by libelf.
+ */
+ stype = SHT_PROGBITS;
+ if (strcmp(sa->name, ".note") == 0 ||
+ strncmp(sa->name, ".note.", strlen(".note.")) == 0)
+ stype = SHT_NOTE;
+
(void) create_external_section(ecp, sa->name, NULL, sa->content,
- sa->size, off, SHT_PROGBITS, ELF_T_BYTE, 0, 1, 0, 0);
+ sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
}
}
@@ -1285,7 +1327,7 @@ update_shdr(struct elfcopy *ecp, int update_link)
continue;
if (gelf_getshdr(s->os, &osh) == NULL)
- errx(EXIT_FAILURE, "668 gelf_getshdr failed: %s",
+ errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
elf_errmsg(-1));
/* Find section name in string table and set sh_name. */
@@ -1364,7 +1406,7 @@ set_shstrtab(struct elfcopy *ecp)
}
if (gelf_getshdr(s->os, &sh) == NULL)
- errx(EXIT_FAILURE, "692 gelf_getshdr() failed: %s",
+ errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
elf_errmsg(-1));
sh.sh_addr = 0;
sh.sh_addralign = 1;
@@ -1431,14 +1473,17 @@ add_section(struct elfcopy *ecp, const char *arg)
if (stat(fn, &sb) == -1)
err(EXIT_FAILURE, "stat failed");
sa->size = sb.st_size;
- if ((sa->content = malloc(sa->size)) == NULL)
- err(EXIT_FAILURE, "malloc failed");
- if ((fp = fopen(fn, "r")) == NULL)
- err(EXIT_FAILURE, "can not open %s", fn);
- if (fread(sa->content, 1, sa->size, fp) == 0 ||
- ferror(fp))
- err(EXIT_FAILURE, "fread failed");
- fclose(fp);
+ if (sa->size > 0) {
+ if ((sa->content = malloc(sa->size)) == NULL)
+ err(EXIT_FAILURE, "malloc failed");
+ if ((fp = fopen(fn, "r")) == NULL)
+ err(EXIT_FAILURE, "can not open %s", fn);
+ if (fread(sa->content, 1, sa->size, fp) == 0 ||
+ ferror(fp))
+ err(EXIT_FAILURE, "fread failed");
+ fclose(fp);
+ } else
+ sa->content = NULL;
STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
ecp->flags |= SEC_ADD;
diff --git a/contrib/elftoolchain/elfcopy/segments.c b/contrib/elftoolchain/elfcopy/segments.c
index 837cea5..8ce0b83 100644
--- a/contrib/elftoolchain/elfcopy/segments.c
+++ b/contrib/elftoolchain/elfcopy/segments.c
@@ -34,7 +34,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: segments.c 3269 2015-12-11 18:38:43Z kaiwang27 $");
+ELFTC_VCSID("$Id: segments.c 3397 2016-02-12 14:35:19Z emaste $");
static void insert_to_inseg_list(struct segment *seg, struct section *sec);
@@ -107,11 +107,11 @@ adjust_addr(struct elfcopy *ecp)
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
/* Only adjust loadable section's address. */
- if (!s->loadable || s->seg == NULL)
+ if (!s->loadable)
continue;
/* Apply global LMA adjustment. */
- if (ecp->change_addr != 0)
+ if (ecp->change_addr != 0 && s->seg != NULL)
s->lma += ecp->change_addr;
if (!s->pseudo) {
@@ -135,7 +135,10 @@ adjust_addr(struct elfcopy *ecp)
*/
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
- /* Only adjust loadable section's LMA. */
+ /*
+ * Only loadable section that's inside a segment can have
+ * LMA adjusted.
+ */
if (!s->loadable || s->seg == NULL)
continue;
@@ -173,7 +176,7 @@ adjust_addr(struct elfcopy *ecp)
if (lma % s->align != 0)
errx(EXIT_FAILURE, "The load address %#jx for "
"section %s is not aligned to %ju",
- (uintmax_t) lma, s->name, s->align);
+ (uintmax_t) lma, s->name, (uintmax_t) s->align);
if (lma < s->lma) {
/* Move section to lower address. */
@@ -214,7 +217,8 @@ adjust_addr(struct elfcopy *ecp)
continue;
errx(EXIT_FAILURE, "The extent of segment containing "
"section %s overlaps with segment(%#jx,%#jx)",
- s->name, seg->addr, seg->addr + seg->msz);
+ s->name, (uintmax_t) seg->addr,
+ (uintmax_t) (seg->addr + seg->msz));
}
/*
@@ -485,7 +489,7 @@ copy_phdr(struct elfcopy *ecp)
ophdr.p_filesz = seg->fsz;
ophdr.p_memsz = seg->msz;
if (!gelf_update_phdr(ecp->eout, i, &ophdr))
- err(EXIT_FAILURE, "gelf_update_phdr failed :%s",
+ errx(EXIT_FAILURE, "gelf_update_phdr failed: %s",
elf_errmsg(-1));
i++;
diff --git a/contrib/elftoolchain/elfcopy/symbols.c b/contrib/elftoolchain/elfcopy/symbols.c
index 05bcd7a..4423ca2 100644
--- a/contrib/elftoolchain/elfcopy/symbols.c
+++ b/contrib/elftoolchain/elfcopy/symbols.c
@@ -25,6 +25,7 @@
*/
#include <sys/param.h>
+#include <assert.h>
#include <err.h>
#include <fnmatch.h>
#include <stdio.h>
@@ -33,7 +34,13 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: symbols.c 3222 2015-05-24 23:47:23Z kaiwang27 $");
+ELFTC_VCSID("$Id: symbols.c 3376 2016-01-26 18:41:39Z emaste $");
+
+/* Backwards compatibility for systems with older ELF definitions. */
+#ifndef STB_GNU_UNIQUE
+#define STB_GNU_UNIQUE 10
+#endif
+
/* Symbol table buffer structure. */
struct symbuf {
@@ -79,7 +86,6 @@ static int lookup_exact_string(hash_head *hash, const char *buf,
static int generate_symbols(struct elfcopy *ecp);
static void mark_reloc_symbols(struct elfcopy *ecp, size_t sc);
static void mark_section_group_symbols(struct elfcopy *ecp, size_t sc);
-static int match_wildcard(const char *name, const char *pattern);
uint32_t str_hash(const char *s);
/* Convenient bit vector operation macros. */
@@ -102,7 +108,8 @@ static int
is_global_symbol(unsigned char st_info)
{
- if (GELF_ST_BIND(st_info) == STB_GLOBAL)
+ if (GELF_ST_BIND(st_info) == STB_GLOBAL ||
+ GELF_ST_BIND(st_info) == STB_GNU_UNIQUE)
return (1);
return (0);
@@ -190,12 +197,6 @@ is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s,
SHN_UNDEF, /* st_shndx */
};
- if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL)
- return (0);
-
- if (lookup_symop_list(ecp, name, SYMOP_STRIP) != NULL)
- return (1);
-
/*
* Keep the first symbol if it is the special reserved symbol.
* XXX Should we generate one if it's missing?
@@ -208,15 +209,34 @@ is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s,
ecp->secndx[s->st_shndx] == 0)
return (1);
+ /* Keep the symbol if specified by command line option -K. */
+ if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL)
+ return (0);
+
if (ecp->strip == STRIP_ALL)
return (1);
+ /* Mark symbols used in relocation. */
if (ecp->v_rel == NULL)
mark_reloc_symbols(ecp, sc);
+ /* Mark symbols used in section groups. */
if (ecp->v_grp == NULL)
mark_section_group_symbols(ecp, sc);
+ /*
+ * Strip the symbol if specified by command line option -N,
+ * unless it's used in relocation.
+ */
+ if (lookup_symop_list(ecp, name, SYMOP_STRIP) != NULL) {
+ if (BIT_ISSET(ecp->v_rel, i)) {
+ warnx("not stripping symbol `%s' because it is named"
+ " in a relocation", name);
+ return (0);
+ }
+ return (1);
+ }
+
if (is_needed_symbol(ecp, i, s))
return (0);
@@ -565,8 +585,11 @@ generate_symbols(struct elfcopy *ecp)
* If the symbol is a STT_SECTION symbol, mark the section
* it points to.
*/
- if (GELF_ST_TYPE(sym.st_info) == STT_SECTION)
+ if (GELF_ST_TYPE(sym.st_info) == STT_SECTION &&
+ sym.st_shndx < SHN_LORESERVE) {
+ assert(ecp->secndx[sym.st_shndx] < (uint64_t)ecp->nos);
BIT_SET(ecp->v_secsym, ecp->secndx[sym.st_shndx]);
+ }
}
/*
@@ -861,6 +884,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
* It handles buffer growing, st_name calculating and st_shndx
* updating for symbols with non-special section index.
*/
+#define _ST_NAME_EMPTY_l 0
+#define _ST_NAME_EMPTY_g -1
#define _ADDSYM(B, SZ) do { \
if (sy_buf->B##SZ == NULL) { \
sy_buf->B##SZ = malloc(sy_buf->B##cap * \
@@ -920,7 +945,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
st_buf->B.sz += strlen(name) + 1; \
} \
} else \
- sy_buf->B##SZ[sy_buf->n##B##s].st_name = 0; \
+ sy_buf->B##SZ[sy_buf->n##B##s].st_name = \
+ (Elf##SZ##_Word)_ST_NAME_EMPTY_##B; \
sy_buf->n##B##s++; \
} while (0)
@@ -945,6 +971,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
ecp->strtab->sz = st_buf->l.sz + st_buf->g.sz;
#undef _ADDSYM
+#undef _ST_NAME_EMPTY_l
+#undef _ST_NAME_EMPTY_g
}
void
@@ -961,10 +989,17 @@ finalize_external_symtab(struct elfcopy *ecp)
sy_buf = ecp->symtab->buf;
st_buf = ecp->strtab->buf;
for (i = 0; (size_t) i < sy_buf->ngs; i++) {
- if (ecp->oec == ELFCLASS32)
- sy_buf->g32[i].st_name += st_buf->l.sz;
- else
- sy_buf->g64[i].st_name += st_buf->l.sz;
+ if (ecp->oec == ELFCLASS32) {
+ if (sy_buf->g32[i].st_name == (Elf32_Word)-1)
+ sy_buf->g32[i].st_name = 0;
+ else
+ sy_buf->g32[i].st_name += st_buf->l.sz;
+ } else {
+ if (sy_buf->g64[i].st_name == (Elf64_Word)-1)
+ sy_buf->g64[i].st_name = 0;
+ else
+ sy_buf->g64[i].st_name += st_buf->l.sz;
+ }
}
}
@@ -1105,46 +1140,47 @@ add_to_symop_list(struct elfcopy *ecp, const char *name, const char *newname,
{
struct symop *s;
- if ((s = lookup_symop_list(ecp, name, ~0U)) == NULL) {
- if ((s = calloc(1, sizeof(*s))) == NULL)
- errx(EXIT_FAILURE, "not enough memory");
- s->name = name;
- if (op == SYMOP_REDEF)
- s->newname = newname;
- }
+ assert (name != NULL);
+ STAILQ_FOREACH(s, &ecp->v_symop, symop_list)
+ if (!strcmp(name, s->name))
+ goto found;
- s->op |= op;
+ if ((s = calloc(1, sizeof(*s))) == NULL)
+ errx(EXIT_FAILURE, "not enough memory");
STAILQ_INSERT_TAIL(&ecp->v_symop, s, symop_list);
-}
-
-static int
-match_wildcard(const char *name, const char *pattern)
-{
- int reverse, match;
-
- reverse = 0;
- if (*pattern == '!') {
- reverse = 1;
- pattern++;
- }
-
- match = 0;
- if (!fnmatch(pattern, name, 0))
- match = 1;
-
- return (reverse ? !match : match);
+ s->name = name;
+found:
+ if (op == SYMOP_REDEF)
+ s->newname = newname;
+ s->op |= op;
}
struct symop *
lookup_symop_list(struct elfcopy *ecp, const char *name, unsigned int op)
{
- struct symop *s;
+ struct symop *s, *ret;
+ const char *pattern;
STAILQ_FOREACH(s, &ecp->v_symop, symop_list) {
- if (name == NULL || !strcmp(name, s->name) ||
- ((ecp->flags & WILDCARD) && match_wildcard(name, s->name)))
- if ((s->op & op) != 0)
+ if ((s->op & op) == 0)
+ continue;
+ if (name == NULL || !strcmp(name, s->name))
return (s);
+ if ((ecp->flags & WILDCARD) == 0)
+ continue;
+
+ /* Handle wildcards. */
+ pattern = s->name;
+ if (pattern[0] == '!') {
+ /* Negative match. */
+ pattern++;
+ ret = NULL;
+ } else {
+ /* Regular wildcard match. */
+ ret = s;
+ }
+ if (!fnmatch(pattern, name, 0))
+ return (ret);
}
return (NULL);
diff --git a/contrib/elftoolchain/elfdump/elfdump.c b/contrib/elftoolchain/elfdump/elfdump.c
index baf99ee..334d285 100644
--- a/contrib/elftoolchain/elfdump/elfdump.c
+++ b/contrib/elftoolchain/elfdump/elfdump.c
@@ -50,7 +50,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: elfdump.c 3250 2015-10-06 13:56:15Z emaste $");
+ELFTC_VCSID("$Id: elfdump.c 3391 2016-02-05 19:43:01Z emaste $");
#if defined(ELFTC_NEED_ELF_NOTE_DEFINITION)
#include "native-elf-format.h"
@@ -155,77 +155,82 @@ le32dec(const void *pp)
static const char *
d_tags(uint64_t tag)
{
+ static char unknown_buf[64];
+
switch (tag) {
- case 0: return "DT_NULL";
- case 1: return "DT_NEEDED";
- case 2: return "DT_PLTRELSZ";
- case 3: return "DT_PLTGOT";
- case 4: return "DT_HASH";
- case 5: return "DT_STRTAB";
- case 6: return "DT_SYMTAB";
- case 7: return "DT_RELA";
- case 8: return "DT_RELASZ";
- case 9: return "DT_RELAENT";
- case 10: return "DT_STRSZ";
- case 11: return "DT_SYMENT";
- case 12: return "DT_INIT";
- case 13: return "DT_FINI";
- case 14: return "DT_SONAME";
- case 15: return "DT_RPATH";
- case 16: return "DT_SYMBOLIC";
- case 17: return "DT_REL";
- case 18: return "DT_RELSZ";
- case 19: return "DT_RELENT";
- case 20: return "DT_PLTREL";
- case 21: return "DT_DEBUG";
- case 22: return "DT_TEXTREL";
- case 23: return "DT_JMPREL";
- case 24: return "DT_BIND_NOW";
- case 25: return "DT_INIT_ARRAY";
- case 26: return "DT_FINI_ARRAY";
- case 27: return "DT_INIT_ARRAYSZ";
- case 28: return "DT_FINI_ARRAYSZ";
- case 29: return "DT_RUNPATH";
- case 30: return "DT_FLAGS";
- case 32: return "DT_PREINIT_ARRAY"; /* XXX: DT_ENCODING */
- case 33: return "DT_PREINIT_ARRAYSZ";
+ case DT_NULL: return "DT_NULL";
+ case DT_NEEDED: return "DT_NEEDED";
+ case DT_PLTRELSZ: return "DT_PLTRELSZ";
+ case DT_PLTGOT: return "DT_PLTGOT";
+ case DT_HASH: return "DT_HASH";
+ case DT_STRTAB: return "DT_STRTAB";
+ case DT_SYMTAB: return "DT_SYMTAB";
+ case DT_RELA: return "DT_RELA";
+ case DT_RELASZ: return "DT_RELASZ";
+ case DT_RELAENT: return "DT_RELAENT";
+ case DT_STRSZ: return "DT_STRSZ";
+ case DT_SYMENT: return "DT_SYMENT";
+ case DT_INIT: return "DT_INIT";
+ case DT_FINI: return "DT_FINI";
+ case DT_SONAME: return "DT_SONAME";
+ case DT_RPATH: return "DT_RPATH";
+ case DT_SYMBOLIC: return "DT_SYMBOLIC";
+ case DT_REL: return "DT_REL";
+ case DT_RELSZ: return "DT_RELSZ";
+ case DT_RELENT: return "DT_RELENT";
+ case DT_PLTREL: return "DT_PLTREL";
+ case DT_DEBUG: return "DT_DEBUG";
+ case DT_TEXTREL: return "DT_TEXTREL";
+ case DT_JMPREL: return "DT_JMPREL";
+ case DT_BIND_NOW: return "DT_BIND_NOW";
+ case DT_INIT_ARRAY: return "DT_INIT_ARRAY";
+ case DT_FINI_ARRAY: return "DT_FINI_ARRAY";
+ case DT_INIT_ARRAYSZ: return "DT_INIT_ARRAYSZ";
+ case DT_FINI_ARRAYSZ: return "DT_FINI_ARRAYSZ";
+ case DT_RUNPATH: return "DT_RUNPATH";
+ case DT_FLAGS: return "DT_FLAGS";
+ case DT_PREINIT_ARRAY: return "DT_PREINIT_ARRAY"; /* XXX DT_ENCODING */
+ case DT_PREINIT_ARRAYSZ:return "DT_PREINIT_ARRAYSZ";
/* 0x6000000D - 0x6ffff000 operating system-specific semantics */
- case 0x6ffffdf5: return "DT_GNU_PRELINKED";
- case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ";
- case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ";
- case 0x6ffffdf8: return "DT_SUNW_CHECKSUM";
- case 0x6ffffdf9: return "DT_PLTPADSZ";
- case 0x6ffffdfa: return "DT_MOVEENT";
- case 0x6ffffdfb: return "DT_MOVESZ";
- case 0x6ffffdfc: return "DT_FEATURE";
- case 0x6ffffdfd: return "DT_POSFLAG_1";
- case 0x6ffffdfe: return "DT_SYMINSZ";
- case 0x6ffffdff: return "DT_SYMINENT (DT_VALRNGHI)";
- case 0x6ffffe00: return "DT_ADDRRNGLO";
- case 0x6ffffef5: return "DT_GNU_HASH";
- case 0x6ffffef8: return "DT_GNU_CONFLICT";
- case 0x6ffffef9: return "DT_GNU_LIBLIST";
- case 0x6ffffefa: return "DT_CONFIG";
- case 0x6ffffefb: return "DT_DEPAUDIT";
- case 0x6ffffefc: return "DT_AUDIT";
- case 0x6ffffefd: return "DT_PLTPAD";
- case 0x6ffffefe: return "DT_MOVETAB";
- case 0x6ffffeff: return "DT_SYMINFO (DT_ADDRRNGHI)";
- case 0x6ffffff9: return "DT_RELACOUNT";
- case 0x6ffffffa: return "DT_RELCOUNT";
- case 0x6ffffffb: return "DT_FLAGS_1";
- case 0x6ffffffc: return "DT_VERDEF";
- case 0x6ffffffd: return "DT_VERDEFNUM";
- case 0x6ffffffe: return "DT_VERNEED";
- case 0x6fffffff: return "DT_VERNEEDNUM";
- case 0x6ffffff0: return "DT_GNU_VERSYM";
+ case 0x6ffffdf5: return "DT_GNU_PRELINKED";
+ case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ";
+ case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ";
+ case 0x6ffffdf8: return "DT_SUNW_CHECKSUM";
+ case DT_PLTPADSZ: return "DT_PLTPADSZ";
+ case DT_MOVEENT: return "DT_MOVEENT";
+ case DT_MOVESZ: return "DT_MOVESZ";
+ case 0x6ffffdfc: return "DT_FEATURE";
+ case DT_POSFLAG_1: return "DT_POSFLAG_1";
+ case DT_SYMINSZ: return "DT_SYMINSZ";
+ case DT_SYMINENT: return "DT_SYMINENT (DT_VALRNGHI)";
+ case DT_ADDRRNGLO: return "DT_ADDRRNGLO";
+ case DT_GNU_HASH: return "DT_GNU_HASH";
+ case 0x6ffffef8: return "DT_GNU_CONFLICT";
+ case 0x6ffffef9: return "DT_GNU_LIBLIST";
+ case 0x6ffffefa: return "DT_CONFIG";
+ case 0x6ffffefb: return "DT_DEPAUDIT";
+ case 0x6ffffefc: return "DT_AUDIT";
+ case 0x6ffffefd: return "DT_PLTPAD";
+ case 0x6ffffefe: return "DT_MOVETAB";
+ case DT_SYMINFO: return "DT_SYMINFO (DT_ADDRRNGHI)";
+ case DT_RELACOUNT: return "DT_RELACOUNT";
+ case DT_RELCOUNT: return "DT_RELCOUNT";
+ case DT_FLAGS_1: return "DT_FLAGS_1";
+ case DT_VERDEF: return "DT_VERDEF";
+ case DT_VERDEFNUM: return "DT_VERDEFNUM";
+ case DT_VERNEED: return "DT_VERNEED";
+ case DT_VERNEEDNUM: return "DT_VERNEEDNUM";
+ case 0x6ffffff0: return "DT_GNU_VERSYM";
/* 0x70000000 - 0x7fffffff processor-specific semantics */
- case 0x70000000: return "DT_IA_64_PLT_RESERVE";
- case 0x7ffffffd: return "DT_SUNW_AUXILIARY";
- case 0x7ffffffe: return "DT_SUNW_USED";
- case 0x7fffffff: return "DT_SUNW_FILTER";
- default: return "ERROR: TAG NOT DEFINED";
+ case 0x70000000: return "DT_IA_64_PLT_RESERVE";
+ case 0x7ffffffd: return "DT_SUNW_AUXILIARY";
+ case 0x7ffffffe: return "DT_SUNW_USED";
+ case 0x7fffffff: return "DT_SUNW_FILTER";
}
+
+ snprintf(unknown_buf, sizeof(unknown_buf),
+ "<unknown: %#llx>", (unsigned long long)tag);
+ return (unknown_buf);
}
static const char *
@@ -313,42 +318,79 @@ sh_name(struct elfdump *ed, int ndx)
/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html#sh_type */
static const char *
-sh_types(u_int64_t sht) {
- switch (sht) {
- case 0: return "SHT_NULL";
- case 1: return "SHT_PROGBITS";
- case 2: return "SHT_SYMTAB";
- case 3: return "SHT_STRTAB";
- case 4: return "SHT_RELA";
- case 5: return "SHT_HASH";
- case 6: return "SHT_DYNAMIC";
- case 7: return "SHT_NOTE";
- case 8: return "SHT_NOBITS";
- case 9: return "SHT_REL";
- case 10: return "SHT_SHLIB";
- case 11: return "SHT_DYNSYM";
- case 14: return "SHT_INIT_ARRAY";
- case 15: return "SHT_FINI_ARRAY";
- case 16: return "SHT_PREINIT_ARRAY";
- case 17: return "SHT_GROUP";
- case 18: return "SHT_SYMTAB_SHNDX";
- /* 0x60000000 - 0x6fffffff operating system-specific semantics */
- case 0x6ffffff0: return "XXX:VERSYM";
- case 0x6ffffff4: return "SHT_SUNW_dof";
- case 0x6ffffff6: return "SHT_GNU_HASH";
- case 0x6ffffff7: return "SHT_GNU_LIBLIST";
- case 0x6ffffffc: return "XXX:VERDEF";
- case 0x6ffffffd: return "SHT_SUNW(GNU)_verdef";
- case 0x6ffffffe: return "SHT_SUNW(GNU)_verneed";
- case 0x6fffffff: return "SHT_SUNW(GNU)_versym";
- /* 0x70000000 - 0x7fffffff processor-specific semantics */
- case 0x70000000: return "SHT_IA_64_EXT";
- case 0x70000001: return "SHT_IA_64_UNWIND";
- case 0x7ffffffd: return "XXX:AUXILIARY";
- case 0x7fffffff: return "XXX:FILTER";
- /* 0x80000000 - 0xffffffff application programs */
- default: return "ERROR: SHT NOT DEFINED";
+sh_types(uint64_t mach, uint64_t sht) {
+ static char unknown_buf[64];
+
+ if (sht < 0x60000000) {
+ switch (sht) {
+ case SHT_NULL: return "SHT_NULL";
+ case SHT_PROGBITS: return "SHT_PROGBITS";
+ case SHT_SYMTAB: return "SHT_SYMTAB";
+ case SHT_STRTAB: return "SHT_STRTAB";
+ case SHT_RELA: return "SHT_RELA";
+ case SHT_HASH: return "SHT_HASH";
+ case SHT_DYNAMIC: return "SHT_DYNAMIC";
+ case SHT_NOTE: return "SHT_NOTE";
+ case SHT_NOBITS: return "SHT_NOBITS";
+ case SHT_REL: return "SHT_REL";
+ case SHT_SHLIB: return "SHT_SHLIB";
+ case SHT_DYNSYM: return "SHT_DYNSYM";
+ case SHT_INIT_ARRAY: return "SHT_INIT_ARRAY";
+ case SHT_FINI_ARRAY: return "SHT_FINI_ARRAY";
+ case SHT_PREINIT_ARRAY: return "SHT_PREINIT_ARRAY";
+ case SHT_GROUP: return "SHT_GROUP";
+ case SHT_SYMTAB_SHNDX: return "SHT_SYMTAB_SHNDX";
+ }
+ } else if (sht < 0x70000000) {
+ /* 0x60000000-0x6fffffff operating system-specific semantics */
+ switch (sht) {
+ case 0x6ffffff0: return "XXX:VERSYM";
+ case SHT_SUNW_dof: return "SHT_SUNW_dof";
+ case SHT_GNU_HASH: return "SHT_GNU_HASH";
+ case 0x6ffffff7: return "SHT_GNU_LIBLIST";
+ case 0x6ffffffc: return "XXX:VERDEF";
+ case SHT_SUNW_verdef: return "SHT_SUNW(GNU)_verdef";
+ case SHT_SUNW_verneed: return "SHT_SUNW(GNU)_verneed";
+ case SHT_SUNW_versym: return "SHT_SUNW(GNU)_versym";
+ }
+ } else if (sht < 0x80000000) {
+ /* 0x70000000 - 0x7fffffff processor-specific semantics */
+ switch (mach) {
+ case EM_ARM:
+ switch (sht) {
+ case SHT_ARM_EXIDX: return "SHT_ARM_EXIDX";
+ case SHT_ARM_PREEMPTMAP: return "SHT_ARM_PREEMPTMAP";
+ case SHT_ARM_ATTRIBUTES: return "SHT_ARM_ATTRIBUTES";
+ case SHT_ARM_DEBUGOVERLAY:
+ return "SHT_ARM_DEBUGOVERLAY";
+ case SHT_ARM_OVERLAYSECTION:
+ return "SHT_ARM_OVERLAYSECTION";
+ }
+ break;
+ case EM_IA_64:
+ switch (sht) {
+ case 0x70000000: return "SHT_IA_64_EXT";
+ case 0x70000001: return "SHT_IA_64_UNWIND";
+ }
+ break;
+ case EM_MIPS:
+ switch (sht) {
+ case SHT_MIPS_REGINFO: return "SHT_MIPS_REGINFO";
+ case SHT_MIPS_OPTIONS: return "SHT_MIPS_OPTIONS";
+ case SHT_MIPS_ABIFLAGS: return "SHT_MIPS_ABIFLAGS";
+ }
+ break;
+ }
+ switch (sht) {
+ case 0x7ffffffd: return "XXX:AUXILIARY";
+ case 0x7fffffff: return "XXX:FILTER";
+ }
}
+ /* 0x80000000 - 0xffffffff application programs */
+
+ snprintf(unknown_buf, sizeof(unknown_buf),
+ "<unknown: %#llx>", (unsigned long long)sht);
+ return (unknown_buf);
}
/*
@@ -390,22 +432,87 @@ sh_flags(uint64_t shf)
return (flg);
}
-static const char *st_types[] = {
- "STT_NOTYPE", "STT_OBJECT", "STT_FUNC", "STT_SECTION", "STT_FILE",
- "STT_COMMON", "STT_TLS"
-};
+static const char *
+st_type(unsigned int mach, unsigned int type)
+{
+ static char s_type[32];
+
+ switch (type) {
+ case STT_NOTYPE: return "STT_NOTYPE";
+ case STT_OBJECT: return "STT_OBJECT";
+ case STT_FUNC: return "STT_FUNC";
+ case STT_SECTION: return "STT_SECTION";
+ case STT_FILE: return "STT_FILE";
+ case STT_COMMON: return "STT_COMMON";
+ case STT_TLS: return "STT_TLS";
+ case 13:
+ if (mach == EM_SPARCV9)
+ return "STT_SPARC_REGISTER";
+ break;
+ }
+ snprintf(s_type, sizeof(s_type), "<unknown: %#x>", type);
+ return (s_type);
+}
-static const char *st_types_S[] = {
- "NOTY", "OBJT", "FUNC", "SECT", "FILE"
-};
+static const char *
+st_type_S(unsigned int type)
+{
+ static char s_type[32];
-static const char *st_bindings[] = {
- "STB_LOCAL", "STB_GLOBAL", "STB_WEAK"
-};
+ switch (type) {
+ case STT_NOTYPE: return "NOTY";
+ case STT_OBJECT: return "OBJT";
+ case STT_FUNC: return "FUNC";
+ case STT_SECTION: return "SECT";
+ case STT_FILE: return "FILE";
+ }
+ snprintf(s_type, sizeof(s_type), "<unknown: %#x>", type);
+ return (s_type);
+}
-static const char *st_bindings_S[] = {
- "LOCL", "GLOB", "WEAK"
-};
+static const char *
+st_bindings(unsigned int sbind)
+{
+ static char s_sbind[32];
+
+ switch (sbind) {
+ case STB_LOCAL: return "STB_LOCAL";
+ case STB_GLOBAL: return "STB_GLOBAL";
+ case STB_WEAK: return "STB_WEAK";
+ case STB_GNU_UNIQUE: return "STB_GNU_UNIQUE";
+ default:
+ if (sbind >= STB_LOOS && sbind <= STB_HIOS)
+ return "OS";
+ else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC)
+ return "PROC";
+ else
+ snprintf(s_sbind, sizeof(s_sbind), "<unknown: %#x>",
+ sbind);
+ return (s_sbind);
+ }
+}
+
+static const char *
+st_bindings_S(unsigned int sbind)
+{
+ static char s_sbind[32];
+
+ switch (sbind) {
+ case STB_LOCAL: return "LOCL";
+ case STB_GLOBAL: return "GLOB";
+ case STB_WEAK: return "WEAK";
+ case STB_GNU_UNIQUE: return "UNIQ";
+ default:
+ if (sbind >= STB_LOOS && sbind <= STB_HIOS)
+ return "OS";
+ else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC)
+ return "PROC";
+ else
+ snprintf(s_sbind, sizeof(s_sbind), "<%#x>",
+ sbind);
+ return (s_sbind);
+ }
+}
static unsigned char st_others[] = {
'D', 'I', 'H', 'P'
@@ -426,7 +533,7 @@ r_type(unsigned int mach, unsigned int type)
case 4: return "R_386_PLT32";
case 5: return "R_386_COPY";
case 6: return "R_386_GLOB_DAT";
- case 7: return "R_386_JMP_SLOT";
+ case 7: return "R_386_JUMP_SLOT";
case 8: return "R_386_RELATIVE";
case 9: return "R_386_GOTOFF";
case 10: return "R_386_GOTPC";
@@ -769,7 +876,7 @@ r_type(unsigned int mach, unsigned int type)
case 4: return "R_X86_64_PLT32";
case 5: return "R_X86_64_COPY";
case 6: return "R_X86_64_GLOB_DAT";
- case 7: return "R_X86_64_JMP_SLOT";
+ case 7: return "R_X86_64_JUMP_SLOT";
case 8: return "R_X86_64_RELATIVE";
case 9: return "R_X86_64_GOTPCREL";
case 10: return "R_X86_64_32";
@@ -1608,7 +1715,8 @@ elf_print_shdr(struct elfdump *ed)
else
PRT(" sh_flags: 0\n");
PRT(" sh_size: %#-14jx", (uintmax_t)s->sz);
- PRT(" sh_type: [ %s ]\n", sh_types(s->type));
+ PRT(" sh_type: [ %s ]\n",
+ sh_types(ed->ehdr.e_machine, s->type));
PRT(" sh_offset: %#-14jx", (uintmax_t)s->off);
PRT(" sh_entsize: %#jx\n", (uintmax_t)s->entsize);
PRT(" sh_link: %-14u", s->link);
@@ -1618,7 +1726,8 @@ elf_print_shdr(struct elfdump *ed)
PRT("\n");
PRT("entry: %ju\n", (uintmax_t)i);
PRT("\tsh_name: %s\n", s->name);
- PRT("\tsh_type: %s\n", sh_types(s->type));
+ PRT("\tsh_type: %s\n",
+ sh_types(ed->ehdr.e_machine, s->type));
PRT("\tsh_flags: %s\n", sh_flags(s->flags));
PRT("\tsh_addr: %#jx\n", (uintmax_t)s->addr);
PRT("\tsh_offset: %ju\n", (uintmax_t)s->off);
@@ -1745,8 +1854,8 @@ elf_print_symtab(struct elfdump *ed, int i)
PRT("0x%8.8jx ", (uintmax_t)sym.st_size);
else
PRT("0x%12.12jx ", (uintmax_t)sym.st_size);
- PRT("%s ", st_types_S[GELF_ST_TYPE(sym.st_info)]);
- PRT("%s ", st_bindings_S[GELF_ST_BIND(sym.st_info)]);
+ PRT("%s ", st_type_S(GELF_ST_TYPE(sym.st_info)));
+ PRT("%s ", st_bindings_S(GELF_ST_BIND(sym.st_info)));
PRT("%c ", st_others[sym.st_other]);
PRT("%3u ", (vs == NULL ? 0 : vs[j]));
PRT("%-11.11s ", sh_name(ed, sym.st_shndx));
@@ -1757,8 +1866,9 @@ elf_print_symtab(struct elfdump *ed, int i)
PRT("\tst_value: %#jx\n", (uintmax_t)sym.st_value);
PRT("\tst_size: %ju\n", (uintmax_t)sym.st_size);
PRT("\tst_info: %s %s\n",
- st_types[GELF_ST_TYPE(sym.st_info)],
- st_bindings[GELF_ST_BIND(sym.st_info)]);
+ st_type(ed->ehdr.e_machine,
+ GELF_ST_TYPE(sym.st_info)),
+ st_bindings(GELF_ST_BIND(sym.st_info)));
PRT("\tst_shndx: %ju\n", (uintmax_t)sym.st_shndx);
}
}
@@ -2173,11 +2283,14 @@ elf_print_got_section(struct elfdump *ed, struct section *s)
for(i = 0; i < len; i++) {
PRT("[%5.5d] ", i);
if (ed->ec == ELFCLASS32) {
- PRT("%-8.8jx ", s->addr + i * s->entsize);
+ PRT("%-8.8jx ",
+ (uintmax_t) (s->addr + i * s->entsize));
PRT("%-8.8x ", *((uint32_t *)dst.d_buf + i));
} else {
- PRT("%-16.16jx ", s->addr + i * s->entsize);
- PRT("%-16.16jx ", *((uint64_t *)dst.d_buf + i));
+ PRT("%-16.16jx ",
+ (uintmax_t) (s->addr + i * s->entsize));
+ PRT("%-16.16jx ",
+ (uintmax_t) *((uint64_t *)dst.d_buf + i));
}
PRT("%-18s ", r_type(ed->ehdr.e_machine,
GELF_R_TYPE(got[i].u_r.rel.r_info)));
@@ -2198,7 +2311,8 @@ elf_print_got_section(struct elfdump *ed, struct section *s)
if (ed->ec == ELFCLASS32)
PRT("\t%#x\n", *((uint32_t *)dst.d_buf + i));
else
- PRT("\t%#jx\n", *((uint64_t *)dst.d_buf + i));
+ PRT("\t%#jx\n",
+ (uintmax_t) *((uint64_t *)dst.d_buf + i));
}
}
}
diff --git a/contrib/elftoolchain/elfdump/os.NetBSD.mk b/contrib/elftoolchain/elfdump/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/elfdump/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h
index e6eb496..6658d2d 100644
--- a/contrib/elftoolchain/libdwarf/_libdwarf.h
+++ b/contrib/elftoolchain/libdwarf/_libdwarf.h
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: _libdwarf.h 3164 2015-02-19 01:20:12Z kaiwang27 $
+ * $Id: _libdwarf.h 3298 2016-01-09 15:43:31Z jkoshy $
*/
#ifndef __LIBDWARF_H_
@@ -92,8 +92,8 @@ extern struct _libdwarf_globals _libdwarf;
typedef struct _Dwarf_CU *Dwarf_CU;
struct _Dwarf_AttrDef {
- uint64_t ad_attrib; /* DW_AT_XXX */
- uint64_t ad_form; /* DW_FORM_XXX */
+ Dwarf_Half ad_attrib; /* DW_AT_XXX */
+ Dwarf_Half ad_form; /* DW_FORM_XXX */
uint64_t ad_offset; /* Offset in abbrev section. */
STAILQ_ENTRY(_Dwarf_AttrDef) ad_next; /* Next attribute define. */
};
@@ -102,8 +102,8 @@ struct _Dwarf_Attribute {
Dwarf_Die at_die; /* Ptr to containing DIE. */
Dwarf_Die at_refdie; /* Ptr to reference DIE. */
uint64_t at_offset; /* Offset in info section. */
- uint64_t at_attrib; /* DW_AT_XXX */
- uint64_t at_form; /* DW_FORM_XXX */
+ Dwarf_Half at_attrib; /* DW_AT_XXX */
+ Dwarf_Half at_form; /* DW_FORM_XXX */
int at_indirect; /* Has indirect form. */
union {
uint64_t u64; /* Unsigned value. */
diff --git a/contrib/elftoolchain/libdwarf/dwarf.3 b/contrib/elftoolchain/libdwarf/dwarf.3
index dbb4179..863bee6 100644
--- a/contrib/elftoolchain/libdwarf/dwarf.3
+++ b/contrib/elftoolchain/libdwarf/dwarf.3
@@ -21,7 +21,7 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: dwarf.3 3195 2015-05-12 17:22:19Z emaste $
+.\" $Id: dwarf.3 3295 2016-01-08 22:08:10Z jkoshy $
.\"
.Dd December 21, 2014
.Os
@@ -110,9 +110,7 @@ A pointer to an error handling function.
.It Vt Dwarf_Line
A descriptor for a source line.
.It Vt Dwarf_Off
-An unsigned file offset, corresponding to an
-.Vt off_t
-type supported by the underlying operating system.
+An unsigned file offset.
.It Vt Dwarf_P_Expr
A descriptor for a location expression.
.It Vt Dwarf_Ptr
diff --git a/contrib/elftoolchain/libdwarf/dwarf_str.c b/contrib/elftoolchain/libdwarf/dwarf_str.c
index 71a7f75..c402f21 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_str.c
+++ b/contrib/elftoolchain/libdwarf/dwarf_str.c
@@ -26,7 +26,7 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: dwarf_str.c 2075 2011-10-27 03:47:28Z jkoshy $");
+ELFTC_VCSID("$Id: dwarf_str.c 3295 2016-01-08 22:08:10Z jkoshy $");
int
dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string,
@@ -34,7 +34,7 @@ dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string,
{
Dwarf_Section *ds;
- if (dbg == NULL || offset < 0 || string == NULL || ret_strlen == NULL) {
+ if (dbg == NULL || string == NULL || ret_strlen == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
@@ -45,12 +45,12 @@ dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string,
return (DW_DLV_NO_ENTRY);
}
- if ((Dwarf_Unsigned) offset > ds->ds_size) {
+ if (offset > ds->ds_size) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
- if ((Dwarf_Unsigned) offset == ds->ds_size) {
+ if (offset == ds->ds_size) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
diff --git a/contrib/elftoolchain/libdwarf/libdwarf.h b/contrib/elftoolchain/libdwarf/libdwarf.h
index 0cb8b1a..02f0ce5 100644
--- a/contrib/elftoolchain/libdwarf/libdwarf.h
+++ b/contrib/elftoolchain/libdwarf/libdwarf.h
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: libdwarf.h 3174 2015-03-27 17:13:41Z emaste $
+ * $Id: libdwarf.h 3295 2016-01-08 22:08:10Z jkoshy $
*/
#ifndef _LIBDWARF_H_
@@ -33,7 +33,7 @@
#include <libelf.h>
typedef int Dwarf_Bool;
-typedef off_t Dwarf_Off;
+typedef uint64_t Dwarf_Off;
typedef uint64_t Dwarf_Unsigned;
typedef uint16_t Dwarf_Half;
typedef uint8_t Dwarf_Small;
diff --git a/contrib/elftoolchain/libdwarf/libdwarf_rw.c b/contrib/elftoolchain/libdwarf/libdwarf_rw.c
index 8cb4551..f0286d5 100644
--- a/contrib/elftoolchain/libdwarf/libdwarf_rw.c
+++ b/contrib/elftoolchain/libdwarf/libdwarf_rw.c
@@ -27,7 +27,7 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 $");
+ELFTC_VCSID("$Id: libdwarf_rw.c 3286 2015-12-31 16:45:46Z emaste $");
uint64_t
_dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
@@ -42,10 +42,13 @@ _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
case 8:
ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
+ /* FALLTHROUGH */
case 4:
ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
+ /* FALLTHROUGH */
case 2:
ret |= ((uint64_t) src[1]) << 8;
+ /* FALLTHROUGH */
case 1:
ret |= src[0];
break;
@@ -71,10 +74,13 @@ _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
case 8:
ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
+ /* FALLTHROUGH */
case 4:
ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
+ /* FALLTHROUGH */
case 2:
ret |= ((uint64_t) src[1]) << 8;
+ /* FALLTHROUGH */
case 1:
ret |= src[0];
break;
@@ -171,11 +177,14 @@ _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
dst[6] = (value >> 48) & 0xff;
dst[5] = (value >> 40) & 0xff;
dst[4] = (value >> 32) & 0xff;
+ /* FALLTHROUGH */
case 4:
dst[3] = (value >> 24) & 0xff;
dst[2] = (value >> 16) & 0xff;
+ /* FALLTHROUGH */
case 2:
dst[1] = (value >> 8) & 0xff;
+ /* FALLTHROUGH */
case 1:
dst[0] = value & 0xff;
break;
@@ -222,13 +231,16 @@ _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
dst[5] = (value >> 16) & 0xff;
dst[4] = (value >> 24) & 0xff;
value >>= 32;
+ /* FALLTHROUGH */
case 4:
dst[3] = value & 0xff;
dst[2] = (value >> 8) & 0xff;
value >>= 16;
+ /* FALLTHROUGH */
case 2:
dst[1] = value & 0xff;
value >>= 8;
+ /* FALLTHROUGH */
case 1:
dst[0] = value & 0xff;
break;
diff --git a/contrib/elftoolchain/libdwarf/os.NetBSD.mk b/contrib/elftoolchain/libdwarf/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/libdwarf/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/libelf/_libelf_config.h b/contrib/elftoolchain/libelf/_libelf_config.h
index 602eb89..1bcf333 100644
--- a/contrib/elftoolchain/libelf/_libelf_config.h
+++ b/contrib/elftoolchain/libelf/_libelf_config.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: _libelf_config.h 3168 2015-02-24 19:17:47Z emaste $
+ * $Id: _libelf_config.h 3396 2016-02-10 21:50:05Z emaste $
*/
#if defined(__APPLE__) || defined(__DragonFly__)
diff --git a/contrib/elftoolchain/libelftc/Makefile b/contrib/elftoolchain/libelftc/Makefile
index a5fc297..4af496b 100644
--- a/contrib/elftoolchain/libelftc/Makefile
+++ b/contrib/elftoolchain/libelftc/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile 2859 2013-01-05 09:21:54Z jkoshy $
+# $Id: Makefile 3292 2016-01-06 21:46:32Z jkoshy $
TOP= ${.CURDIR}/..
@@ -45,16 +45,7 @@ MLINKS= elftc_bfd_find_target.3 elftc_bfd_target_byteorder.3 \
elftc_string_table_create.3 elftc_string_table_destroy.3 \
elftc_string_table_create.3 elftc_string_table_image.3 \
elftc_string_table_create.3 elftc_string_table_insert.3 \
- elftc_string_table_create.3 elftc_string_table_lookup.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_create_nested.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_delete_name.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_delete_entry.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_destroy.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_from_section.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_insert.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_iterate.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_lookup.3 \
- elftc_symbol_table_create.3 elftc_symbol_table_to_image.3
+ elftc_string_table_create.3 elftc_string_table_lookup.3
.if !make(clean) && !make(clobber)
.BEGIN: .SILENT
diff --git a/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 b/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3
index 851ae31..20dea3c 100644
--- a/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3
+++ b/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3
@@ -21,7 +21,7 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elftc_bfd_find_target.3 2251 2011-11-30 16:50:06Z jkoshy $
+.\" $Id: elftc_bfd_find_target.3 3348 2016-01-18 14:18:50Z emaste $
.\"
.Dd November 30, 2011
.Os
@@ -58,9 +58,11 @@ Binary object descriptors encapsulate properties of an object format
such as its file representation, ELF class, and byte endianness.
.Pp
Known descriptor names and their properties include:
-.Bl -column -offset "XXXX" ".Li elf32-x86-64-freebsd" "Object format" "Byte Order" "ELF Class"
-.It Em Name Ta Em "Object Format" Ta Em "Byte Order" Ta Em "ELF Class"
+.Bl -column -offset "XXXX" ".Li elf32-x86-64-freebsd" "Object format" "Byte Order" "Bit Width"
+.It Em Name Ta Em "Object Format" Ta Em "Byte Order" Ta Em "Bit Width"
.It Li binary Ta Binary Ta - Ta -
+.It Li efi-app-ia32 Ta PE Ta LSB Ta 32
+.It Li efi-app-x86_64 Ta PE Ta LSB Ta 64
.It Li elf32-avr Ta ELF Ta LSB Ta 32
.It Li elf32-big Ta ELF Ta MSB Ta 32
.It Li elf32-bigarm Ta ELF Ta MSB Ta 32
@@ -101,6 +103,8 @@ Known descriptor names and their properties include:
.It Li elf64-x86-64 Ta ELF Ta LSB Ta 64
.It Li elf64-x86-64-freebsd Ta ELF Ta LSB Ta 64
.It Li ihex Ta IHEX Ta - Ta -
+.It Li pei-i386 Ta PE Ta LSB Ta 32
+.It Li pei-x86-64 Ta PE Ta LSB Ta 64
.It Li srec Ta SREC Ta - Ta -
.It Li symbolsrec Ta SREC Ta - Ta -
.El
diff --git a/contrib/elftoolchain/libelftc/elftc_copyfile.c b/contrib/elftoolchain/libelftc/elftc_copyfile.c
index 7df1678..dac9c14 100644
--- a/contrib/elftoolchain/libelftc/elftc_copyfile.c
+++ b/contrib/elftoolchain/libelftc/elftc_copyfile.c
@@ -37,7 +37,7 @@
#include <sys/mman.h>
#endif
-ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $");
+ELFTC_VCSID("$Id: elftc_copyfile.c 3297 2016-01-09 15:26:34Z jkoshy $");
/*
* Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on
@@ -47,11 +47,11 @@ ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $");
int
elftc_copyfile(int ifd, int ofd)
{
+ size_t file_size, n;
int buf_mmapped;
struct stat sb;
char *b, *buf;
- ssize_t nw;
- size_t n;
+ ssize_t nr, nw;
/* Determine the input file's size. */
if (fstat(ifd, &sb) < 0)
@@ -63,12 +63,13 @@ elftc_copyfile(int ifd, int ofd)
buf = NULL;
buf_mmapped = 0;
+ file_size = (size_t) sb.st_size;
#if ELFTC_HAVE_MMAP
/*
* Prefer mmap() if it is available.
*/
- buf = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0);
+ buf = mmap(NULL, file_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0);
if (buf != MAP_FAILED)
buf_mmapped = 1;
else
@@ -80,24 +81,27 @@ elftc_copyfile(int ifd, int ofd)
* failed, allocate a buffer, and read in input data.
*/
if (buf_mmapped == false) {
- if ((buf = malloc(sb.st_size)) == NULL)
- return (-1);
- if (read(ifd, buf, sb.st_size) != sb.st_size) {
- free(buf);
+ if ((buf = malloc(file_size)) == NULL)
return (-1);
+ b = buf;
+ for (n = file_size; n > 0; n -= (size_t) nr, b += nr) {
+ if ((nr = read(ifd, b, n)) < 0) {
+ free(buf);
+ return (-1);
+ }
}
}
/*
* Write data to the output file descriptor.
*/
- for (n = sb.st_size, b = buf; n > 0; n -= nw, b += nw)
+ for (n = file_size, b = buf; n > 0; n -= (size_t) nw, b += nw)
if ((nw = write(ofd, b, n)) <= 0)
break;
/* Release the input buffer. */
#if ELFTC_HAVE_MMAP
- if (buf_mmapped && munmap(buf, sb.st_size) < 0)
+ if (buf_mmapped && munmap(buf, file_size) < 0)
return (-1);
#endif
diff --git a/contrib/elftoolchain/libelftc/elftc_demangle.c b/contrib/elftoolchain/libelftc/elftc_demangle.c
index ff30955..945f777 100644
--- a/contrib/elftoolchain/libelftc/elftc_demangle.c
+++ b/contrib/elftoolchain/libelftc/elftc_demangle.c
@@ -33,10 +33,10 @@
#include "_libelftc.h"
-ELFTC_VCSID("$Id: elftc_demangle.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: elftc_demangle.c 3296 2016-01-09 14:17:28Z jkoshy $");
-static int
-is_mangled(const char *s, int style)
+static unsigned int
+is_mangled(const char *s, unsigned int style)
{
switch (style) {
@@ -58,7 +58,7 @@ is_mangled(const char *s, int style)
}
static char *
-demangle(const char *s, int style, int rc)
+demangle(const char *s, unsigned int style, unsigned int rc)
{
(void) rc; /* XXX */
@@ -76,7 +76,7 @@ int
elftc_demangle(const char *mangledname, char *buffer, size_t bufsize,
unsigned int flags)
{
- int style, rc;
+ unsigned int style, rc;
char *rlt;
style = flags & 0xFFFF;
diff --git a/contrib/elftoolchain/libelftc/elftc_symbol_table_create.3 b/contrib/elftoolchain/libelftc/elftc_symbol_table_create.3
deleted file mode 100644
index 76f90e9..0000000
--- a/contrib/elftoolchain/libelftc/elftc_symbol_table_create.3
+++ /dev/null
@@ -1,529 +0,0 @@
-.\" Copyright (c) 2012 Joseph Koshy. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" This software is provided by Joseph Koshy ``as is'' and
-.\" any express or implied warranties, including, but not limited to, the
-.\" implied warranties of merchantability and fitness for a particular purpose
-.\" are disclaimed. in no event shall Joseph Koshy be liable
-.\" for any direct, indirect, incidental, special, exemplary, or consequential
-.\" damages (including, but not limited to, procurement of substitute goods
-.\" or services; loss of use, data, or profits; or business interruption)
-.\" however caused and on any theory of liability, whether in contract, strict
-.\" liability, or tort (including negligence or otherwise) arising in any way
-.\" out of the use of this software, even if advised of the possibility of
-.\" such damage.
-.\"
-.\" $Id: elftc_symbol_table_create.3 3182 2015-04-10 16:08:10Z emaste $
-.\"
-.Dd December 29, 2012
-.Os
-.Dt ELFTC_SYMBOL_TABLE_CREATE 3
-.Sh NAME
-.Nm elftc_elf_symbol_table_from_section ,
-.Nm elftc_symbol_table_count ,
-.Nm elftc_symbol_table_create ,
-.Nm elftc_symbol_table_create_nested ,
-.Nm elftc_symbol_table_delete_name ,
-.Nm elftc_symbol_table_delete_entry ,
-.Nm elftc_symbol_table_destroy ,
-.Nm elftc_symbol_table_insert ,
-.Nm elftc_symbol_table_iterate ,
-.Nm elftc_symbol_table_lookup ,
-.Nm elftc_symbol_table_lookup_value ,
-.Nm elftc_symbol_table_replace ,
-.Nm elftc_symbol_table_sort ,
-.Nm elftc_symbol_table_step
-.Nd symbol table management routines
-.Sh SYNOPSIS
-.In libelftc.h
-.Bd -literal
-typedef struct _Elftc_Symbol_Table Elftc_Symbol_Table;
-
-typedef struct _Elftc_Symbol {
- ... library private fields ...
- const char *sym_name;
- uintptr_t sym_value;
-} Elftc_Symbol;
-.Ed
-.Ft size_t
-.Fn elftc_symbol_table_count "Elftc_Symbol_Table *table"
-.Ft "Elftc_Symbol_Table *"
-.Fo elftc_symbol_table_create
-.Fa "size_t entrysize"
-.Fa "int sizehint"
-.Fc
-.Ft "Elftc_Symbol_Table *"
-.Fo elftc_symbol_table_create_nested
-.Fa "Elftc_Symbol_Table *table"
-.Fa "int sizehint"
-.Fc
-.Ft int
-.Fo elftc_symbol_table_delete_name
-.Fa "Elftc_Symbol_Table *table"
-.Fa "const char *name"
-.Fc
-.Ft int
-.Fo elftc_symbol_table_delete_entry
-.Fa "Elftc_Symbol_Table *table"
-.Fa "Elftc_Symbol *entry"
-.Fc
-.Ft int
-.Fn elftc_symbol_table_destroy "Elftc_Symbol_Table *table"
-.Ft "Elftc_Symbol *entry"
-.Fo elftc_symbol_table_insert
-.Fa "Elftc_Symbol_Table *table"
-.Fa "const char *symbolname"
-.Fa "int *status"
-.Fc
-.Ft int
-.Fo elftc_symbol_table_iterate
-.Fa "Elftc_Symbol_Table *table"
-.Fa "int (*iterfn)(Elftc_Symbol *entry, void *cookie)"
-.Fa "void *cookie"
-.Fc
-.Ft "Elftc_Symbol *"
-.Fo elftc_symbol_table_lookup
-.Fa "Elftc_Symbol_Table *table"
-.Fa "const char *symbolname"
-.Fc
-.Ft "Elftc_Elf_Symbol *"
-.Fo elftc_symbol_table_lookup_value
-.Fa "Elftc_Symbol_Table *table"
-.Fa "uintptr_t value"
-.Fa "int searchflags"
-.Fc
-.Ft int
-.Fo elftc_symbol_table_replace
-.Fa "Elftc_Symbol_Table *table"
-.Fa "Elftc_Symbol *sym1"
-.Fa "Elftc_Symbol *sym2"
-.Fc
-.Ft int
-.Fo elftc_symbol_table_sort
-.Fa "Elftc_Symbol_Table *table"
-.Fa "int (*cmpfn)(Elftc_Symbol *s1, Elftc_Symbol *s2)"
-.Fc
-.Ft "Elftc_Symbol *"
-.Fo elftc_symbol_table_step
-.Fa "Elftc_Symbol_Table *table"
-.Fa "Elftc_Symbol *cursym"
-.Fa "int direction"
-.Fc
-.Bd -literal
-typedef struct _Elftc_Elf_Symbol {
- ... library private fields ...
- const char *sym_name;
- Gelf_Sym sym_elf;
-} Elftc_Elf_Symbol;
-.Ed
-.Ft "Elftc_Symbol_Table *"
-.Fo elftc_elf_symbol_table_from_section
-.Fa "Elf_Scn *symscn"
-.Fa "Elf_Scn *strscn"
-.Fc
-.Sh DESCRIPTION
-This manual page documents convenience routines for handling symbol
-tables.
-Two flavors of symbol tables are supported:
-.Bl -bullet -compact
-.It
-.Dq Regular
-symbol tables supporting insertion, deletion and lookup of entries by
-name or by value, sorting of entries, and stepping through entries in
-the table's current traversal order.
-.It
-.Dq ELF-centric
-symbol tables support additional operations for conversions to and
-from the symbol table format understood by
-.Lb libelf .
-.El
-The default traversal order for a symbol table is the order in which
-entries were inserted into it.
-This traversal order may be changed using function
-.Fn elftc_symbol_table_sort .
-.Ss Operations on Regular Symbol Tables
-Regular symbol tables use symbols that are subtypes of
-.Vt Elftc_Symbol ,
-as described in the section
-.Sx "Structure of a Symbol Table Entry"
-below.
-.Pp
-Function
-.Fn elftc_symbol_table_count
-returns the number of entries currently in the symbol table.
-.Pp
-Function
-.Fn elftc_symbol_table_create
-creates a new, empty symbol table.
-The argument
-.Ar entrysize
-specifies the size of each symbol table entry, as described
-in the section
-.Sx "Structure of a Symbol Table Entry"
-below.
-The argument
-.Ar sizehint
-specifies the expected number of symbol table entries.
-If
-.Ar sizehint
-is zero, an implementation-defined default will be used.
-.Pp
-Function
-.Fn elftc_symbol_table_create_nested
-creates a symbol table whose search scope nests inside that of a
-parent symbol table.
-The argument
-.Ar parent
-specifies the parent symbol table to nest under.
-The argument
-.Ar sizehint
-specifies the expected number of symbol table entries.
-If
-.Ar sizehint
-is zero, an implementation-defined default will be used instead.
-.Pp
-The function
-.Fn elftc_symbol_table_delete_name
-removes the symbol entry named by the argument
-.Ar name
-from the symbol table specified by argument
-.Ar table ,
-according to the rules described in section
-.Sx "Symbol Search Rules" .
-.Pp
-The function
-.Fn elftc_symbol_table_delete_entry
-removes the symbol table entry specified by argument
-.Ar entry
-from the symbol table specified by argument
-.Ar table .
-.Pp
-Function
-.Fn elftc_symbol_table_destroy
-is used to destroy a symbol table and free up its internal
-resources.
-.Pp
-The function
-.Fn elftc_symbol_table_insert
-inserts a symbol entry for the name specified by argument
-.Ar symbolname
-into the symbol table specified by argument
-.Ar table ,
-returning a pointer to a symbol table entry.
-The argument
-.Ar status
-should point to a location that will be updated with one of
-the following values:
-.Bl -tag -width indent -compact -offset indent
-.It Dv ELFTC_INSERT_ERROR
-An error occurred during insertion of the symbol.
-.It Dv ELFTC_INSERT_EXISTING
-The name in argument
-.Ar symbolname
-was already in the symbol table, and a pointer to the existing
-symbol table entry is being returned.
-.It Dv ELFTC_INSERT_NEW
-A new symbol table entry was allocated for the symbol name
-in
-.Ar symbolname .
-The application will need to initialize the application-specific
-fields of the symbol table entry.
-.El
-Insertion obeys the scoping rules described in section
-.Sx "Symbol Search Rules" .
-.Pp
-The function
-.Fn elftc_symbol_table_iterate
-iterates over the symbol table specifed by argument
-.Ar table ,
-applying the function pointed to by argument
-.Ar iterfn
-to each symbol table entry.
-The return value from the function
-.Ar iterfn
-controls progress of the iteration:
-.Bl -tag -width indent -compact -offset indent
-.It Dv ELFTC_ITERATE_ABORT
-Terminates the iteration.
-.It Dv ELFTC_ITERATE_CONTINUE
-Iteration will continue on to the next element in the symbol table.
-.El
-Argument
-.Ar cookie
-will be passed to each invocation of
-.Ar iterfn ,
-and may be used to track persistent state.
-The ordering of symbol table entries presented to function
-.Ar iterfn
-is not defined.
-The behavior of the iteration is undefined if
-.Ar iterfn
-adds or deletes symbol entries from a symbol table that currently
-being iterated through.
-.Pp
-Function
-.Fn elftc_symbol_table_lookup
-returns the symbol entry corresponding to the name of the symbol
-in argument
-.Ar symbolname .
-.Pp
-Function
-.Fn elftc_symbol_table_lookup_value
-returns the symbol entry that has a
-.Va sym_value
-field that is closest to the value specified in argument
-.Ar value .
-The argument
-.Ar table
-should point to a symbol table, that has been sorted
-by a prior call to
-.Fn elftc_symbol_table_sort .
-The argument
-.Ar searchflags
-can be a combination of the following flags:
-.Bl -tag -width indent -compact -offset indent
-.It Dv ELFTC_SEARCH_FORWARD
-Find the symbol entry with the next higher value in its
-.Va sym_value
-field.
-.It Dv ELFTC_SEARCH_BACKWARD
-Find the symbol entry with next lower value in its
-.Va sym_value
-field.
-.El
-If both
-.Dv ELFTC_SEARCH_FORWARD
-and
-.Dv ELFTC_SEARCH_BACKWARD
-are specified, then this function will return the symbol that is
-closest to the argument
-.Ar value .
-.Pp
-Function
-.Fn elftc_symbol_table_replace
-moves the symbol table entry pointed to by argument
-.Ar sym2
-into the traversal position for the entry pointed to by
-.Ar sym1 ,
-and implicitly deletes the entry pointed to by argument
-.Ar sym1 .
-Argument
-.Ar table
-should point to a valid symbol table.
-.Pp
-Function
-.Fn elftc_symbol_table_sort
-is used to define an ordering of symbol entries in a symbol
-table.
-This ordering will be associated with the symbol table till the next
-call to function
-.Fn elftc_symbol_table_insert ,
-.Fn elftc_symbol_table_delete_name
-or
-.Fn elftc_symbol_table_delete_entry .
-The argument
-.Ar cmpfn
-should point to a function that compares two symbol entries pointed
-to by
-.Ar s1
-and
-.Ar s2
-and returns -1, 0, or 1, depending whether
-.Ar s1
-is less, equal to, or greater than
-.Ar s2
-respectively.
-.Pp
-Function
-.Fn elftc_symbol_table_step
-is used to step to the next symbol in a sorted symbol table.
-Argument
-.Ar table
-should point to a symbol table.
-The argument
-.Ar cursym
-specifies the current symbol.
-The argument
-.Ar direction
-specifies the direction to step:
-.Bl -tag -width indent -compact -offset ident
-.It Dv ELFTC_STEP_NEXT
-Return the symbol which follows the argument
-.Ar cursym
-in the current traversal order.
-If argument
-.Ar cursym
-is NULL, return the first symbol in the current
-traversal order.
-.It Dv ELFTC_STEP_PREVIOUS
-Return the symbol which precedes the argument
-.Ar cursym
-in the current traversal order.
-If argument
-.Ar cursym
-is NULL, return the last symbol in the current
-traversal order.
-.El
-.Ss Operations on ELF-centric symbol tables
-ELF-centric symbol tables use symbols that are subtypes of
-.Vt Elftc_Elf_Symbol ,
-as described in the section
-.Sx "Structure of a Symbol Table Entry"
-below.
-.Pp
-In addition to the operations on regular symbol tables listed above,
-these symbol tables may be used with the following additional
-functions.
-.Pp
-The function
-.Fn elftc_elf_symbol_table_from_section
-builds a symbol table from the contents of an ELF section.
-The argument
-.Ar symscn
-should reference an ELF section of type
-.Dv SHT_SYMTAB
-or
-.Dv SHT_DYNSYM .
-The argument
-.Ar strscn
-should reference an ELF section of type
-.Dv SHT_STRTAB
-containing the string table associated wit section
-.Ar symscn .
-.Ss Structure of a Symbol Table Entry
-The symbol tables managed by
-.Lb libelftc
-are collections of symbol table entries.
-Each entry should be a subtype of one of the
-.Vt Elftc_Symbol
-or
-.Vt Elftc_Elf_Symbol
-types.
-In other words, each entry should have an
-.Vt Elftc_Symbol
-or
-.Vt Elftc_Elf_Symbol
-structure as its first member, before any application specific
-fields.
-For example:
-.Bd -literal -offset indent
-struct _MySymbol {
- Elftc_Symbol sym_base;
- ... other application-specific fields ...
-};
-.Ed
-.Pp
-The size of the combined entry is indicated to the library
-at the time of creating a new symbol table.
-Applications may then cast the returned pointers from these
-routines to the appropriate type:
-.Bd -literal -offset indent
-struct _MySymbol *mysym;
-
-mysym = (struct _MySymbol *) elftc_symbol_table_lookup(table,
- name);
-.Ed
-.Pp
-The
-.Vt Elftc_Symbol
-type has two public fields:
-.Bl -tag -width ".Va sym_value" -compact -offset indent
-.It Va sym_name
-Points to a NUL-terminated string containing the symbol's name.
-The application should not change the value of this field.
-.It Va sym_value
-The value associated with this symbol.
-This field is entirely under the application's control.
-.El
-.Pp
-The
-.Vt Elftc_Elf_Symbol
-type has two public fields:
-.Bl -tag -width ".Va sym_value" -compact -offset indent
-.It Va sym_name
-Points to a NUL-terminated string containing the symbol's name.
-The application should not change the value of this field.
-.It Va sym_elf
-A structure of type
-.Vt Gelf_Sym
-containing ELF symbol information.
-This field is entirely under the application's control.
-.El
-.Ss Symbol Search Rules
-During lookups, symbols are looked up first in the symbol table passed in
-to the
-.Fn elftc_symbol_table_lookup
-function.
-If the specified symbol is not found, and if the symbol table has a
-parent, then the search continues recursively up the chain of parent
-symbol tables till either a matching symbol is found or till there are
-no more parent symbol tables to search in.
-.Pp
-Insertions and deletion only work on the specified symbol table and
-do not recurse into parent symbol tables.
-.Ss Memory Management
-The
-.Lb libelftc
-manages its memory allocations.
-Applications should not free the pointers returned by the
-API documented in this manual page.
-.Sh RETURN VALUES
-Function
-.Fn elftc_symbol_table_count
-returns a count of the number of symbol table entries as an unsigned
-value.
-.Pp
-Functions
-.Fn elftc_symbol_table_create ,
-.Fn elftc_symbol_table_create_nested
-and
-.Fn elftc_symbol_table_from_section
-return a pointer to an opaque structure of type
-.Vt Elftc_Symbol_Table
-on success, or return NULL in case of an error.
-.Pp
-Functions
-.Fn elftc_symbol_table_delete_name ,
-.Fn elftc_symbol_table_delete_name
-.Fn elftc_symbol_table_destroy ,
-.Fn elftc_symbol_table_replace
-and
-.Fn elftc_symbol_table_sort
-return a non-zero value on success, or return zero in case of an error.
-.Pp
-Functions
-.Fn elftc_symbol_table_insert ,
-.Fn elftc_symbol_table_lookup
-and
-.Fn elftc_symbol_table_lookup_value
-return a pointer to a structure that is a subtype of
-.Vt Elftc_Symbol
-on success, or return NULL in case of an error.
-.Pp
-The function
-.Fn elftc_symbol_table_step
-return a pointer to a structure that is a subtype of
-.Vt Elftc_Symbol
-on success.
-The function returns NULL if there are no more elements in the
-specified traversal direction.
-.Pp
-The function
-.Fn elftc_symbol_table_iterate
-returns
-.Dv ELFTC_ITERATE_SUCCESS
-if the symbol table was successfully traversed, or
-.Dv ELFTC_ITERATE_ABORT
-in case the iteration function aborted the traversal.
-.Sh SEE ALSO
-.Xr dwarf 3 ,
-.Xr elf 3 ,
-.Xr elftc 3
diff --git a/contrib/elftoolchain/libelftc/libelftc.h b/contrib/elftoolchain/libelftc/libelftc.h
index 062db31..e3adaf2 100644
--- a/contrib/elftoolchain/libelftc/libelftc.h
+++ b/contrib/elftoolchain/libelftc/libelftc.h
@@ -24,7 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $
- * $Id: libelftc.h 3174 2015-03-27 17:13:41Z emaste $
+ * $Id: libelftc.h 3309 2016-01-10 09:10:51Z kaiwang27 $
*/
#ifndef _LIBELFTC_H_
@@ -46,7 +46,9 @@ typedef enum {
ETF_ELF,
ETF_BINARY,
ETF_SREC,
- ETF_IHEX
+ ETF_IHEX,
+ ETF_PE,
+ ETF_EFI,
} Elftc_Bfd_Target_Flavor;
/*
diff --git a/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c b/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c
index 00ba225..88f3220 100644
--- a/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c
+++ b/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c
@@ -30,7 +30,7 @@
#include "_libelftc.h"
-ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3309 2016-01-10 09:10:51Z kaiwang27 $");
struct _Elftc_Bfd_Target _libelftc_targets[] = {
@@ -375,6 +375,30 @@ struct _Elftc_Bfd_Target _libelftc_targets[] = {
},
{
+ .bt_name = "efi-app-ia32",
+ .bt_type = ETF_EFI,
+ .bt_machine = EM_386,
+ },
+
+ {
+ .bt_name = "efi-app-x86_64",
+ .bt_type = ETF_EFI,
+ .bt_machine = EM_X86_64,
+ },
+
+ {
+ .bt_name = "pei-i386",
+ .bt_type = ETF_PE,
+ .bt_machine = EM_386,
+ },
+
+ {
+ .bt_name = "pei-x86-64",
+ .bt_type = ETF_PE,
+ .bt_machine = EM_X86_64,
+ },
+
+ {
.bt_name = NULL,
.bt_type = ETF_NONE,
},
diff --git a/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c b/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
index e8fd78f..f5ca7b3 100644
--- a/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
+++ b/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
@@ -36,7 +36,7 @@
#include "_libelftc.h"
-ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3212 2015-05-17 13:40:55Z kaiwang27 $");
+ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3291 2016-01-04 02:36:38Z emaste $");
/**
* @file cpp_demangle.c
@@ -1262,11 +1262,13 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
if (!cpp_demangle_push_str(ddata,
"non-transaction clone for ", 26))
return (0);
+ break;
case 't':
default:
if (!cpp_demangle_push_str(ddata,
"transaction clone for ", 22))
return (0);
+ break;
}
++ddata->cur;
return (cpp_demangle_read_encoding(ddata));
@@ -1895,35 +1897,35 @@ cpp_demangle_read_subst(struct cpp_demangle_data *ddata)
case SIMPLE_HASH('S', 'd'):
/* std::basic_iostream<char, std::char_traits<char> > */
- if (!cpp_demangle_push_str(ddata, "std::iostream", 19))
+ if (!cpp_demangle_push_str(ddata, "std::basic_iostream", 19))
return (0);
- ddata->last_sname = "iostream";
+ ddata->last_sname = "basic_iostream";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
- "std::iostream", 19));
+ "std::basic_iostream", 19));
return (1);
case SIMPLE_HASH('S', 'i'):
/* std::basic_istream<char, std::char_traits<char> > */
- if (!cpp_demangle_push_str(ddata, "std::istream", 18))
+ if (!cpp_demangle_push_str(ddata, "std::basic_istream", 18))
return (0);
- ddata->last_sname = "istream";
+ ddata->last_sname = "basic_istream";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
- "std::istream", 18));
+ "std::basic_istream", 18));
return (1);
case SIMPLE_HASH('S', 'o'):
/* std::basic_ostream<char, std::char_traits<char> > */
- if (!cpp_demangle_push_str(ddata, "std::ostream", 18))
+ if (!cpp_demangle_push_str(ddata, "std::basic_ostream", 18))
return (0);
- ddata->last_sname = "istream";
+ ddata->last_sname = "basic_ostream";
ddata->cur += 2;
if (*ddata->cur == 'I')
return (cpp_demangle_read_subst_stdtmpl(ddata,
- "std::ostream", 18));
+ "std::basic_ostream", 18));
return (1);
case SIMPLE_HASH('S', 's'):
diff --git a/contrib/elftoolchain/libelftc/make-toolchain-version b/contrib/elftoolchain/libelftc/make-toolchain-version
index ac6155a..8891258 100755
--- a/contrib/elftoolchain/libelftc/make-toolchain-version
+++ b/contrib/elftoolchain/libelftc/make-toolchain-version
@@ -3,7 +3,7 @@
# This script generates a project-wide version identifier for use by
# the `elftc_version()' API.
#
-# $Id: make-toolchain-version 2583 2012-09-14 09:49:25Z jkoshy $
+# $Id: make-toolchain-version 3299 2016-01-09 19:58:46Z jkoshy $
#
# Defaults.
@@ -64,7 +64,7 @@ done
curdir=`pwd`
cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"."
-if [ -d .svn ]; then # FreeBSD and SF.Net sources.
+if [ -d .svn -o -d ../.svn ]; then # FreeBSD and SF.Net sources.
versionstring=" svn:"$(svnversion)
elif [ -d CVS ]; then # NetBSD.
versionstring=" cvs:unknown"
diff --git a/contrib/elftoolchain/libelftc/os.NetBSD.mk b/contrib/elftoolchain/libelftc/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/libelftc/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/libpe/Makefile b/contrib/elftoolchain/libpe/Makefile
new file mode 100644
index 0000000..d02fb50
--- /dev/null
+++ b/contrib/elftoolchain/libpe/Makefile
@@ -0,0 +1,32 @@
+# $Id: Makefile 3349 2016-01-18 21:09:16Z jkoshy $
+
+TOP= ${.CURDIR}/..
+
+LIB= pe
+
+SRCS= libpe_buffer.c \
+ libpe_coff.c \
+ libpe_dos.c \
+ libpe_init.c \
+ libpe_rich.c \
+ libpe_section.c \
+ libpe_utils.c \
+ pe_buffer.c \
+ pe_cntl.c \
+ pe_coff.c \
+ pe_dos.c \
+ pe_flag.c \
+ pe_init.c \
+ pe_rich.c \
+ pe_section.c \
+ pe_symtab.c \
+ pe_update.c
+
+INCS= libpe.h pe.h
+INCSDIR= /usr/include
+
+SHLIB_MAJOR= 1
+
+WARNS?= 6
+
+.include "${TOP}/mk/elftoolchain.lib.mk"
diff --git a/contrib/elftoolchain/libpe/_libpe.h b/contrib/elftoolchain/libpe/_libpe.h
new file mode 100644
index 0000000..1a83a67
--- /dev/null
+++ b/contrib/elftoolchain/libpe/_libpe.h
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: _libpe.h 3312 2016-01-10 09:23:51Z kaiwang27 $
+ */
+
+#ifndef __LIBPE_H_
+#define __LIBPE_H_
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include "libpe.h"
+
+#include "_elftc.h"
+
+typedef struct _PE_SecBuf {
+ PE_Buffer sb_pb; /* application buffer */
+ PE_Scn *sb_ps; /* PE_Scn pointer */
+ unsigned int sb_flags; /* buffer flags */
+ STAILQ_ENTRY(_PE_SecBuf) sb_next;
+} PE_SecBuf;
+
+struct _PE_Scn {
+ PE *ps_pe; /* PE descriptor */
+ PE_SecHdr ps_sh; /* section header */
+ unsigned int ps_ndx; /* 1-based section index */
+ unsigned int ps_flags; /* section flags */
+ unsigned int ps_falign; /* section file alignment */
+ STAILQ_HEAD(, _PE_SecBuf) ps_b; /* buffer list */
+ STAILQ_ENTRY(_PE_Scn) ps_next;
+};
+
+struct _PE {
+ int pe_fd; /* file descriptor */
+ PE_Cmd pe_cmd; /* open mode */
+ PE_Object pe_obj; /* PE32/PE32+/COFF */
+ size_t pe_fsize; /* file size */
+ unsigned int pe_flags; /* library flags */
+ PE_DosHdr *pe_dh; /* MS-DOS header */
+ char *pe_stub; /* MS-DOS stub */
+ size_t pe_stub_ex; /* MS-DOS stub len (exclude hdr) */
+ char *pe_stub_app; /* MS-DOS stub (app supplied) */
+ size_t pe_stub_app_sz; /* MS-DOS stub len (app supplied) */
+ PE_RichHdr *pe_rh; /* rich header */
+ char *pe_rh_start; /* pointer to rich header */
+ PE_CoffHdr *pe_ch; /* COFF header */
+ PE_OptHdr *pe_oh; /* optional header */
+ PE_DataDir *pe_dd; /* data directories */
+ unsigned int pe_nscn; /* num. of sections */
+ char *pe_symtab; /* COFF symbol table */
+ size_t pe_symbtab_sz; /* size of symbol table */
+ unsigned int pe_nsym; /* num. of symbols */
+ unsigned int pe_rvamax; /* maximum RVA */
+ STAILQ_HEAD(, _PE_Scn) pe_scn; /* section list */
+};
+
+/* Library internal flags */
+#define LIBPE_F_API_MASK 0x000FFFU
+#define LIBPE_F_SPECIAL_FILE 0x001000U
+#define LIBPE_F_BAD_DOS_HEADER 0x002000U
+#define LIBPE_F_BAD_PE_HEADER 0x004000U
+#define LIBPE_F_BAD_COFF_HEADER 0x008000U
+#define LIBPE_F_BAD_OPT_HEADER 0x010000U
+#define LIBPE_F_BAD_SEC_HEADER 0x020000U
+#define LIBPE_F_LOAD_DOS_STUB 0x040000U
+#define LIBPE_F_FD_DONE 0x080000U
+#define LIBPE_F_DIRTY_DOS_HEADER 0x100000U
+#define LIBPE_F_DIRTY_COFF_HEADER 0x200000U
+#define LIBPE_F_DIRTY_OPT_HEADER 0x400000U
+#define LIBPE_F_DIRTY_SEC_HEADER 0x800000U
+
+/* Internal section flags */
+#define LIBPE_F_LOAD_SECTION 0x1000U
+#define LIBPE_F_STRIP_SECTION 0x2000U
+
+/* Internal buffer flags */
+#define LIBPE_F_BUFFER_MALLOCED 0x1000U
+
+/* Library internal defines */
+#define PE_DOS_MAGIC 0x5a4dU
+#define PE_RICH_TEXT "Rich"
+#define PE_RICH_HIDDEN 0x536e6144U /* DanS */
+#define PE_SIGNATURE 0x4550U /* PE\0\0 */
+#define PE_COFF_OPT_SIZE_32 224
+#define PE_COFF_OPT_SIZE_32P 240
+#define PE_SYM_ENTRY_SIZE 18
+
+/* Encode/Decode macros */
+#if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS)
+static __inline uint16_t
+le16dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return ((p[1] << 8) | p[0]);
+}
+
+static __inline uint32_t
+le32dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+}
+
+static __inline uint64_t
+le64dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
+}
+
+static __inline void
+le16enc(void *pp, uint16_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+}
+
+static __inline void
+le32enc(void *pp, uint32_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+ p[2] = (u >> 16) & 0xff;
+ p[3] = (u >> 24) & 0xff;
+}
+
+static __inline void
+le64enc(void *pp, uint64_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ le32enc(p, (uint32_t)(u & 0xffffffffU));
+ le32enc(p + 4, (uint32_t)(u >> 32));
+}
+#endif /* ELFTC_NEED_BYTEORDER_EXTENSIONS */
+
+#define PE_READ16(p,v) do { \
+ (v) = le16dec((p)); \
+ (p) += 2; \
+} while(0)
+
+#define PE_READ32(p,v) do { \
+ (v) = le32dec((p)); \
+ (p) += 4; \
+} while(0)
+
+#define PE_WRITE16(p,v) do { \
+ le16enc((p), (v)); \
+ (p) += 2; \
+} while(0)
+
+#define PE_WRITE32(p,v) do { \
+ le32enc((p), (v)); \
+ (p) += 4; \
+} while(0)
+
+
+/* Internal function declarations */
+off_t libpe_align(PE *, off_t, size_t);
+PE_SecBuf *libpe_alloc_buffer(PE_Scn *, size_t);
+PE_Scn *libpe_alloc_scn(PE *);
+int libpe_load_all_sections(PE *);
+int libpe_load_section(PE *, PE_Scn *);
+int libpe_open_object(PE *);
+int libpe_pad(PE *, size_t);
+int libpe_parse_msdos_header(PE *, char *);
+int libpe_parse_coff_header(PE *, char *);
+int libpe_parse_rich_header(PE *);
+int libpe_parse_section_headers(PE *);
+int libpe_read_msdos_stub(PE *);
+void libpe_release_buffer(PE_SecBuf *);
+void libpe_release_object(PE *);
+void libpe_release_scn(PE_Scn *);
+size_t libpe_resync_buffers(PE_Scn *);
+int libpe_resync_sections(PE *, off_t);
+int libpe_write_buffers(PE_Scn *);
+off_t libpe_write_coff_header(PE *, off_t);
+off_t libpe_write_msdos_stub(PE *, off_t);
+off_t libpe_write_pe_header(PE *, off_t);
+off_t libpe_write_sections(PE *, off_t);
+off_t libpe_write_section_headers(PE *, off_t);
+
+#endif /* !__LIBPE_H_ */
diff --git a/contrib/elftoolchain/libpe/libpe.h b/contrib/elftoolchain/libpe/libpe.h
new file mode 100644
index 0000000..3cec39a
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe.h
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: libpe.h 3312 2016-01-10 09:23:51Z kaiwang27 $
+ */
+
+#ifndef _LIBPE_H_
+#define _LIBPE_H_
+
+#include <sys/types.h>
+
+#include "pe.h"
+
+/* Library private data structures */
+typedef struct _PE PE;
+typedef struct _PE_Scn PE_Scn;
+
+/* Section buffers */
+typedef struct PE_Buffer {
+ unsigned int pb_align;
+ off_t pb_off;
+ size_t pb_size;
+ void *pb_buf;
+} PE_Buffer;
+
+/* Object types */
+typedef enum {
+ PE_O_UNKNOWN = 0,
+ PE_O_PE32,
+ PE_O_PE32P,
+ PE_O_COFF,
+} PE_Object;
+
+/* Commands */
+typedef enum {
+ PE_C_NULL = 0,
+ PE_C_CLR,
+ PE_C_FDDONE,
+ PE_C_FDREAD,
+ PE_C_RDWR,
+ PE_C_READ,
+ PE_C_SET,
+ PE_C_WRITE,
+ PE_C_NUM
+} PE_Cmd;
+
+/* Flags defined by the API. */
+#define PE_F_DIRTY 0x001U
+#define PE_F_STRIP_DOS_STUB 0x002U
+#define PE_F_STRIP_RICH_HEADER 0x004U
+#define PE_F_STRIP_SYMTAB 0x008U
+#define PE_F_STRIP_DEBUG 0x010U
+#define PE_F_STRIP_SECTION 0x020U
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PE_CoffHdr *pe_coff_header(PE *);
+int pe_cntl(PE *, PE_Cmd);
+PE_DataDir *pe_data_dir(PE *);
+void pe_finish(PE *);
+int pe_flag(PE *, PE_Cmd, unsigned int);
+int pe_flag_buffer(PE_Buffer *, PE_Cmd, unsigned int);
+int pe_flag_coff_header(PE *, PE_Cmd, unsigned int);
+int pe_flag_data_dir(PE *, PE_Cmd, unsigned int);
+int pe_flag_dos_header(PE *, PE_Cmd, unsigned int);
+int pe_flag_opt_header(PE *, PE_Cmd, unsigned int);
+int pe_flag_section_header(PE_Scn *, PE_Cmd, unsigned int);
+int pe_flag_scn(PE_Scn *, PE_Cmd, unsigned int);
+PE_Buffer *pe_getbuffer(PE_Scn *, PE_Buffer *);
+PE_Scn *pe_getscn(PE *, size_t);
+PE *pe_init(int, PE_Cmd, PE_Object);
+PE_Scn *pe_insertscn(PE *, size_t);
+PE_DosHdr *pe_msdos_header(PE *);
+char *pe_msdos_stub(PE *, size_t *);
+size_t pe_ndxscn(PE_Scn *);
+PE_Buffer *pe_newbuffer(PE_Scn *);
+PE_Scn *pe_newscn(PE *);
+PE_Scn *pe_nextscn(PE *, PE_Scn *);
+PE_Object pe_object(PE *);
+PE_OptHdr *pe_opt_header(PE *);
+PE_RichHdr *pe_rich_header(PE *);
+int pe_rich_header_validate(PE *);
+PE_SecHdr *pe_section_header(PE_Scn *);
+off_t pe_update(PE *);
+int pe_update_coff_header(PE *, PE_CoffHdr *);
+int pe_update_opt_header(PE *, PE_OptHdr *);
+int pe_update_data_dir(PE *, PE_DataDir *);
+int ps_update_msdos_header(PE *, PE_DosHdr *);
+int ps_update_msdos_stub(PE *, char *, size_t);
+int pe_update_section_header(PE_Scn *, PE_SecHdr *);
+int pe_update_symtab(PE *, char *, size_t, unsigned int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_LIBPE_H_ */
diff --git a/contrib/elftoolchain/libpe/libpe_buffer.c b/contrib/elftoolchain/libpe/libpe_buffer.c
new file mode 100644
index 0000000..cc633dd
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_buffer.c
@@ -0,0 +1,185 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_buffer.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_SecBuf *
+libpe_alloc_buffer(PE_Scn *ps, size_t sz)
+{
+ PE_SecBuf *sb;
+
+ if ((sb = malloc(sizeof(PE_SecBuf))) == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+
+ sb->sb_ps = ps;
+ sb->sb_flags = 0;
+ sb->sb_pb.pb_align = 1;
+ sb->sb_pb.pb_off = 0;
+ sb->sb_pb.pb_size = sz;
+ if (sz > 0) {
+ if ((sb->sb_pb.pb_buf = malloc(sz)) == NULL) {
+ free(sb);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ sb->sb_flags |= LIBPE_F_BUFFER_MALLOCED;
+ } else
+ sb->sb_pb.pb_buf = NULL;
+
+ STAILQ_INSERT_TAIL(&ps->ps_b, sb, sb_next);
+
+ return (sb);
+}
+
+void
+libpe_release_buffer(PE_SecBuf *sb)
+{
+ PE_Scn *ps;
+
+ assert(sb != NULL);
+
+ ps = sb->sb_ps;
+
+ STAILQ_REMOVE(&ps->ps_b, sb, _PE_SecBuf, sb_next);
+
+ if (sb->sb_flags & LIBPE_F_BUFFER_MALLOCED)
+ free(sb->sb_pb.pb_buf);
+
+ free(sb);
+}
+
+static int
+cmp_sb(PE_SecBuf *a, PE_SecBuf *b)
+{
+
+ if (a->sb_pb.pb_off < b->sb_pb.pb_off)
+ return (-1);
+ else if (a->sb_pb.pb_off == b->sb_pb.pb_off)
+ return (0);
+ else
+ return (1);
+}
+
+static void
+sort_buffers(PE_Scn *ps)
+{
+
+ if (STAILQ_EMPTY(&ps->ps_b))
+ return;
+
+ STAILQ_SORT(&ps->ps_b, _PE_SecBuf, sb_next, cmp_sb);
+}
+
+size_t
+libpe_resync_buffers(PE_Scn *ps)
+{
+ PE_SecBuf *sb;
+ PE_Buffer *pb;
+ size_t sz;
+
+ assert(ps->ps_flags & LIBPE_F_LOAD_SECTION);
+
+ sort_buffers(ps);
+
+ sz = 0;
+ STAILQ_FOREACH(sb, &ps->ps_b, sb_next) {
+ if (ps->ps_flags & PE_F_DIRTY)
+ sb->sb_flags |= PE_F_DIRTY;
+
+ pb = (PE_Buffer *) sb;
+ if (pb->pb_align > ps->ps_falign)
+ pb->pb_align = ps->ps_falign;
+ if (pb->pb_buf == NULL || pb->pb_size == 0)
+ continue;
+
+ sz = roundup(sz, pb->pb_align);
+
+ if (pb->pb_off != (off_t) sz) {
+ pb->pb_off = sz;
+ sb->sb_flags |= PE_F_DIRTY;
+ }
+ sz += pb->pb_size;
+ }
+
+ return (sz);
+}
+
+int
+libpe_write_buffers(PE_Scn *ps)
+{
+ PE *pe;
+ PE_SecBuf *sb;
+ PE_Buffer *pb;
+ off_t off;
+
+ assert(ps->ps_flags & LIBPE_F_LOAD_SECTION);
+
+ pe = ps->ps_pe;
+
+ off = 0;
+ STAILQ_FOREACH(sb, &ps->ps_b, sb_next) {
+ pb = &sb->sb_pb;
+ if (pb->pb_buf == NULL || pb->pb_size == 0)
+ continue;
+
+ if ((sb->sb_flags & PE_F_DIRTY) == 0) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+ if (lseek(pe->pe_fd, (off_t) pb->pb_size, SEEK_CUR) <
+ 0) {
+ errno = EIO;
+ return (-1);
+ }
+ goto next_buf;
+ }
+
+ if (pb->pb_off > off) {
+ if (libpe_pad(pe, pb->pb_off - off) < 0)
+ return (-1);
+ off = pb->pb_off;
+ }
+
+ if (write(pe->pe_fd, pb->pb_buf, pb->pb_size) !=
+ (ssize_t) pb->pb_size) {
+ errno = EIO;
+ return (-1);
+ }
+
+ next_buf:
+ off += pb->pb_size;
+ }
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/libpe_coff.c b/contrib/elftoolchain/libpe/libpe_coff.c
new file mode 100644
index 0000000..e161f7c
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_coff.c
@@ -0,0 +1,535 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_coff.c 3326 2016-01-16 17:46:17Z kaiwang27 $");
+
+int
+libpe_parse_coff_header(PE *pe, char *hdr)
+{
+ char tmp[128];
+ PE_CoffHdr *ch;
+ PE_OptHdr *oh;
+ PE_DataDir *dd;
+ unsigned p, r, s;
+ int i;
+
+ if ((ch = malloc(sizeof(PE_CoffHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ PE_READ16(hdr, ch->ch_machine);
+ PE_READ16(hdr, ch->ch_nsec);
+ PE_READ32(hdr, ch->ch_timestamp);
+ PE_READ32(hdr, ch->ch_symptr);
+ PE_READ32(hdr, ch->ch_nsym);
+ PE_READ16(hdr, ch->ch_optsize);
+ PE_READ16(hdr, ch->ch_char);
+
+ pe->pe_ch = ch;
+
+ /*
+ * The Optional header is omitted for object files.
+ */
+ if (ch->ch_optsize == 0)
+ return (libpe_parse_section_headers(pe));
+
+ if ((oh = calloc(1, sizeof(PE_OptHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_oh = oh;
+
+#define READ_OPT(n) \
+ do { \
+ /* \
+ * Since the Optional Header size is variable, we must \
+ * check if the requested read size will overrun the \
+ * remaining header bytes. \
+ */ \
+ if (p + (n) > ch->ch_optsize) { \
+ /* Consume the "extra" bytes */ \
+ r = ch->ch_optsize - p; \
+ if (read(pe->pe_fd, tmp, r) != (ssize_t) r) { \
+ pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER;\
+ return (0); \
+ } \
+ return (libpe_parse_section_headers(pe)); \
+ } \
+ if (read(pe->pe_fd, tmp, (n)) != (ssize_t) (n)) { \
+ pe->pe_flags |= LIBPE_F_BAD_OPT_HEADER; \
+ return (0); \
+ } \
+ p += (n); \
+ } while (0)
+#define READ_OPT8(v) do { READ_OPT(1); (v) = *tmp; } while(0)
+#define READ_OPT16(v) do { READ_OPT(2); (v) = le16dec(tmp); } while(0)
+#define READ_OPT32(v) do { READ_OPT(4); (v) = le32dec(tmp); } while(0)
+#define READ_OPT64(v) do { READ_OPT(8); (v) = le64dec(tmp); } while(0)
+
+ /*
+ * Read in the Optional header. Size of some fields are depending
+ * on the PE format specified by the oh_magic field. (PE32 or PE32+)
+ */
+
+ p = 0;
+ READ_OPT16(oh->oh_magic);
+ if (oh->oh_magic == PE_FORMAT_32P)
+ pe->pe_obj = PE_O_PE32P;
+ READ_OPT8(oh->oh_ldvermajor);
+ READ_OPT8(oh->oh_ldverminor);
+ READ_OPT32(oh->oh_textsize);
+ READ_OPT32(oh->oh_datasize);
+ READ_OPT32(oh->oh_bsssize);
+ READ_OPT32(oh->oh_entry);
+ READ_OPT32(oh->oh_textbase);
+ if (oh->oh_magic != PE_FORMAT_32P) {
+ READ_OPT32(oh->oh_database);
+ READ_OPT32(oh->oh_imgbase);
+ } else
+ READ_OPT64(oh->oh_imgbase);
+ READ_OPT32(oh->oh_secalign);
+ READ_OPT32(oh->oh_filealign);
+ READ_OPT16(oh->oh_osvermajor);
+ READ_OPT16(oh->oh_osverminor);
+ READ_OPT16(oh->oh_imgvermajor);
+ READ_OPT16(oh->oh_imgverminor);
+ READ_OPT16(oh->oh_subvermajor);
+ READ_OPT16(oh->oh_subverminor);
+ READ_OPT32(oh->oh_win32ver);
+ READ_OPT32(oh->oh_imgsize);
+ READ_OPT32(oh->oh_hdrsize);
+ READ_OPT32(oh->oh_checksum);
+ READ_OPT16(oh->oh_subsystem);
+ READ_OPT16(oh->oh_dllchar);
+ if (oh->oh_magic != PE_FORMAT_32P) {
+ READ_OPT32(oh->oh_stacksizer);
+ READ_OPT32(oh->oh_stacksizec);
+ READ_OPT32(oh->oh_heapsizer);
+ READ_OPT32(oh->oh_heapsizec);
+ } else {
+ READ_OPT64(oh->oh_stacksizer);
+ READ_OPT64(oh->oh_stacksizec);
+ READ_OPT64(oh->oh_heapsizer);
+ READ_OPT64(oh->oh_heapsizec);
+ }
+ READ_OPT32(oh->oh_ldrflags);
+ READ_OPT32(oh->oh_ndatadir);
+
+ /*
+ * Read in the Data Directories.
+ */
+
+ if (oh->oh_ndatadir > 0) {
+ if ((dd = calloc(1, sizeof(PE_DataDir))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_dd = dd;
+
+ dd->dd_total = oh->oh_ndatadir < PE_DD_MAX ? oh->oh_ndatadir :
+ PE_DD_MAX;
+
+ for (i = 0; (uint32_t) i < dd->dd_total; i++) {
+ READ_OPT32(dd->dd_e[i].de_addr);
+ READ_OPT32(dd->dd_e[i].de_size);
+ }
+ }
+
+ /* Consume the remaining bytes in the Optional header, if any. */
+ if (ch->ch_optsize > p) {
+ r = ch->ch_optsize - p;
+ for (; r > 0; r -= s) {
+ s = r > sizeof(tmp) ? sizeof(tmp) : r;
+ if (read(pe->pe_fd, tmp, s) != (ssize_t) s) {
+ pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER;
+ return (0);
+ }
+ }
+ }
+
+ return (libpe_parse_section_headers(pe));
+}
+
+off_t
+libpe_write_pe_header(PE *pe, off_t off)
+{
+ char tmp[4];
+
+ if (pe->pe_cmd == PE_C_RDWR &&
+ (pe->pe_flags & LIBPE_F_BAD_PE_HEADER) == 0) {
+ assert(pe->pe_dh != NULL);
+ off = lseek(pe->pe_fd, (off_t) pe->pe_dh->dh_lfanew + 4,
+ SEEK_SET);
+ return (off);
+ }
+
+ /*
+ * PE Header should to be aligned on 8-byte boundary according to
+ * the PE/COFF specification.
+ */
+ if ((off = libpe_align(pe, off, 8)) < 0)
+ return (-1);
+
+ le32enc(tmp, PE_SIGNATURE);
+ if (write(pe->pe_fd, tmp, sizeof(tmp)) != (ssize_t) sizeof(tmp)) {
+ errno = EIO;
+ return (-1);
+ }
+
+ off += 4;
+
+ pe->pe_flags &= ~LIBPE_F_BAD_PE_HEADER;
+
+ /* Trigger rewrite for the following headers. */
+ pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER;
+ pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER;
+
+ return (off);
+}
+
+off_t
+libpe_write_coff_header(PE *pe, off_t off)
+{
+ char tmp[128], *hdr;
+ PE_CoffHdr *ch;
+ PE_DataDir *dd;
+ PE_OptHdr *oh;
+ PE_Scn *ps;
+ PE_SecHdr *sh;
+ unsigned p;
+ uint32_t reloc_rva, reloc_sz;
+ int i, reloc;
+
+ reloc = 0;
+ reloc_rva = reloc_sz = 0;
+
+ if (pe->pe_cmd == PE_C_RDWR) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+
+ if ((pe->pe_flags & LIBPE_F_DIRTY_COFF_HEADER) == 0 &&
+ (pe->pe_flags & LIBPE_F_BAD_COFF_HEADER) == 0) {
+ if (lseek(pe->pe_fd, (off_t) sizeof(PE_CoffHdr),
+ SEEK_CUR) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ off += sizeof(PE_CoffHdr);
+ assert(pe->pe_ch != NULL);
+ ch = pe->pe_ch;
+ goto coff_done;
+ }
+
+ /* lseek(2) to the offset of the COFF header. */
+ if (lseek(pe->pe_fd, off, SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+ if (pe->pe_ch == NULL) {
+ if ((ch = calloc(1, sizeof(PE_CoffHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_ch = ch;
+
+ /*
+ * Default value for ch_machine if not provided by the
+ * application.
+ */
+ if (pe->pe_obj == PE_O_PE32P)
+ ch->ch_machine = IMAGE_FILE_MACHINE_AMD64;
+ else
+ ch->ch_machine = IMAGE_FILE_MACHINE_I386;
+
+ } else
+ ch = pe->pe_ch;
+
+ if (!ch->ch_timestamp)
+ ch->ch_timestamp = time(NULL);
+
+ if (pe->pe_obj == PE_O_PE32) {
+ if (!ch->ch_optsize)
+ ch->ch_optsize = PE_COFF_OPT_SIZE_32;
+ ch->ch_char |= IMAGE_FILE_EXECUTABLE_IMAGE |
+ IMAGE_FILE_32BIT_MACHINE;
+ } else if (pe->pe_obj == PE_O_PE32P) {
+ if (!ch->ch_optsize)
+ ch->ch_optsize = PE_COFF_OPT_SIZE_32P;
+ ch->ch_char |= IMAGE_FILE_EXECUTABLE_IMAGE |
+ IMAGE_FILE_LARGE_ADDRESS_AWARE;
+ } else
+ ch->ch_optsize = 0;
+
+ /*
+ * COFF line number is deprecated by the PE/COFF
+ * specification. COFF symbol table is deprecated
+ * for executables.
+ */
+ ch->ch_char |= IMAGE_FILE_LINE_NUMS_STRIPPED;
+ if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P)
+ ch->ch_char |= IMAGE_FILE_LOCAL_SYMS_STRIPPED;
+
+ ch->ch_nsec = pe->pe_nscn;
+
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ sh = &ps->ps_sh;
+
+ if (ps->ps_ndx == 0xFFFFFFFFU) {
+ ch->ch_symptr = sh->sh_rawptr;
+ ch->ch_nsym = pe->pe_nsym;
+ }
+
+ if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) {
+ if (ps->ps_ndx == (0xFFFF0000 | PE_DD_BASERELOC) ||
+ strncmp(sh->sh_name, ".reloc", strlen(".reloc")) ==
+ 0) {
+ reloc = 1;
+ reloc_rva = sh->sh_addr;
+ reloc_sz = sh->sh_virtsize;
+ }
+ }
+ }
+
+ if (!reloc)
+ ch->ch_char |= IMAGE_FILE_RELOCS_STRIPPED;
+
+ if (pe->pe_flags & LIBPE_F_BAD_OPT_HEADER) {
+ if (pe->pe_obj == PE_O_PE32)
+ ch->ch_optsize = PE_COFF_OPT_SIZE_32;
+ else if (pe->pe_obj == PE_O_PE32P)
+ ch->ch_optsize = PE_COFF_OPT_SIZE_32P;
+ else
+ ch->ch_optsize = 0;
+ }
+
+ /*
+ * Write the COFF header.
+ */
+ hdr = tmp;
+ PE_WRITE16(hdr, ch->ch_machine);
+ PE_WRITE16(hdr, ch->ch_nsec);
+ PE_WRITE32(hdr, ch->ch_timestamp);
+ PE_WRITE32(hdr, ch->ch_symptr);
+ PE_WRITE32(hdr, ch->ch_nsym);
+ PE_WRITE16(hdr, ch->ch_optsize);
+ PE_WRITE16(hdr, ch->ch_char);
+ if (write(pe->pe_fd, tmp, sizeof(PE_CoffHdr)) !=
+ (ssize_t) sizeof(PE_CoffHdr)) {
+ errno = EIO;
+ return (-1);
+ }
+
+coff_done:
+ off += sizeof(PE_CoffHdr);
+ pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER;
+ pe->pe_flags &= ~LIBPE_F_BAD_COFF_HEADER;
+ pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
+
+ if (ch->ch_optsize == 0)
+ return (off);
+
+ /*
+ * Write the Optional header.
+ */
+
+ if (pe->pe_cmd == PE_C_RDWR) {
+ if ((pe->pe_flags & LIBPE_F_DIRTY_OPT_HEADER) == 0 &&
+ (pe->pe_flags & LIBPE_F_BAD_OPT_HEADER) == 0) {
+ if (lseek(pe->pe_fd, (off_t) ch->ch_optsize,
+ SEEK_CUR) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ off += ch->ch_optsize;
+ return (off);
+ }
+
+ }
+
+ if (pe->pe_oh == NULL) {
+ if ((oh = calloc(1, sizeof(PE_OptHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_oh = oh;
+ } else
+ oh = pe->pe_oh;
+
+ if (pe->pe_obj == PE_O_PE32)
+ oh->oh_magic = PE_FORMAT_32;
+ else
+ oh->oh_magic = PE_FORMAT_32P;
+
+ /*
+ * LinkerVersion should not be less than 2.5, which will cause
+ * Windows to complain the executable is invalid in some case.
+ * By default we set LinkerVersion to 2.22 (binutils 2.22)
+ */
+ if (!oh->oh_ldvermajor && !oh->oh_ldverminor) {
+ oh->oh_ldvermajor = 2;
+ oh->oh_ldverminor = 22;
+ }
+
+ /*
+ * The library always tries to write out all 16 data directories
+ * but the actual data dir written will depend on ch_optsize.
+ */
+ oh->oh_ndatadir = PE_DD_MAX;
+
+ if (!oh->oh_filealign)
+ oh->oh_filealign = 0x200;
+ if (!oh->oh_secalign)
+ oh->oh_secalign = 0x1000;
+ oh->oh_hdrsize = roundup(off + ch->ch_optsize + pe->pe_nscn *
+ sizeof(PE_SecHdr), oh->oh_filealign);
+ oh->oh_imgsize = roundup(pe->pe_rvamax, oh->oh_secalign);
+
+#define WRITE_OPT(n) \
+ do { \
+ /* \
+ * Since the Optional Header size is variable, we must \
+ * check if the requested write size will overrun the \
+ * remaining header bytes. \
+ */ \
+ if (p + (n) > ch->ch_optsize) { \
+ /* Pad the "extra" bytes */ \
+ if (libpe_pad(pe, ch->ch_optsize - p) < 0) { \
+ errno = EIO; \
+ return (-1); \
+ } \
+ goto opt_done; \
+ } \
+ if (write(pe->pe_fd, tmp, (n)) != (ssize_t) (n)) { \
+ errno = EIO; \
+ return (-1); \
+ } \
+ p += (n); \
+ } while (0)
+#define WRITE_OPT8(v) do { *tmp = (v); WRITE_OPT(1); } while(0)
+#define WRITE_OPT16(v) do { le16enc(tmp, (v)); WRITE_OPT(2); } while(0)
+#define WRITE_OPT32(v) do { le32enc(tmp, (v)); WRITE_OPT(4); } while(0)
+#define WRITE_OPT64(v) do { le64enc(tmp, (v)); WRITE_OPT(8); } while(0)
+
+ p = 0;
+ WRITE_OPT16(oh->oh_magic);
+ if (oh->oh_magic == PE_FORMAT_32P)
+ pe->pe_obj = PE_O_PE32P;
+ WRITE_OPT8(oh->oh_ldvermajor);
+ WRITE_OPT8(oh->oh_ldverminor);
+ WRITE_OPT32(oh->oh_textsize);
+ WRITE_OPT32(oh->oh_datasize);
+ WRITE_OPT32(oh->oh_bsssize);
+ WRITE_OPT32(oh->oh_entry);
+ WRITE_OPT32(oh->oh_textbase);
+ if (oh->oh_magic != PE_FORMAT_32P) {
+ WRITE_OPT32(oh->oh_database);
+ WRITE_OPT32(oh->oh_imgbase);
+ } else
+ WRITE_OPT64(oh->oh_imgbase);
+ WRITE_OPT32(oh->oh_secalign);
+ WRITE_OPT32(oh->oh_filealign);
+ WRITE_OPT16(oh->oh_osvermajor);
+ WRITE_OPT16(oh->oh_osverminor);
+ WRITE_OPT16(oh->oh_imgvermajor);
+ WRITE_OPT16(oh->oh_imgverminor);
+ WRITE_OPT16(oh->oh_subvermajor);
+ WRITE_OPT16(oh->oh_subverminor);
+ WRITE_OPT32(oh->oh_win32ver);
+ WRITE_OPT32(oh->oh_imgsize);
+ WRITE_OPT32(oh->oh_hdrsize);
+ WRITE_OPT32(oh->oh_checksum);
+ WRITE_OPT16(oh->oh_subsystem);
+ WRITE_OPT16(oh->oh_dllchar);
+ if (oh->oh_magic != PE_FORMAT_32P) {
+ WRITE_OPT32(oh->oh_stacksizer);
+ WRITE_OPT32(oh->oh_stacksizec);
+ WRITE_OPT32(oh->oh_heapsizer);
+ WRITE_OPT32(oh->oh_heapsizec);
+ } else {
+ WRITE_OPT64(oh->oh_stacksizer);
+ WRITE_OPT64(oh->oh_stacksizec);
+ WRITE_OPT64(oh->oh_heapsizer);
+ WRITE_OPT64(oh->oh_heapsizec);
+ }
+ WRITE_OPT32(oh->oh_ldrflags);
+ WRITE_OPT32(oh->oh_ndatadir);
+
+ /*
+ * Write the Data Directories.
+ */
+
+ if (oh->oh_ndatadir > 0) {
+ if (pe->pe_dd == NULL) {
+ if ((dd = calloc(1, sizeof(PE_DataDir))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_dd = dd;
+ dd->dd_total = PE_DD_MAX;
+ } else
+ dd = pe->pe_dd;
+
+ assert(oh->oh_ndatadir <= PE_DD_MAX);
+
+ if (reloc) {
+ dd->dd_e[PE_DD_BASERELOC].de_addr = reloc_rva;
+ dd->dd_e[PE_DD_BASERELOC].de_size = reloc_sz;
+ }
+
+ for (i = 0; (uint32_t) i < dd->dd_total; i++) {
+ WRITE_OPT32(dd->dd_e[i].de_addr);
+ WRITE_OPT32(dd->dd_e[i].de_size);
+ }
+ }
+
+ /* Pad the remaining bytes in the Optional header, if any. */
+ if (ch->ch_optsize > p) {
+ if (libpe_pad(pe, ch->ch_optsize - p) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+opt_done:
+ off += ch->ch_optsize;
+ pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER;
+ pe->pe_flags &= ~LIBPE_F_BAD_OPT_HEADER;
+ pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
+
+ return (off);
+}
diff --git a/contrib/elftoolchain/libpe/libpe_dos.c b/contrib/elftoolchain/libpe/libpe_dos.c
new file mode 100644
index 0000000..a48ad12
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_dos.c
@@ -0,0 +1,403 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_dos.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+int
+libpe_parse_msdos_header(PE *pe, char *hdr)
+{
+ PE_DosHdr *dh;
+ char coff[sizeof(PE_CoffHdr)];
+ uint32_t pe_magic;
+ int i;
+
+ if ((pe->pe_stub = malloc(sizeof(PE_DosHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ memcpy(pe->pe_stub, hdr, sizeof(PE_DosHdr));
+
+ if ((dh = malloc(sizeof(*dh))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_dh = dh;
+
+ /* Read the conventional MS-DOS EXE header. */
+ memcpy(dh->dh_magic, hdr, 2);
+ hdr += 2;
+ PE_READ16(hdr, dh->dh_lastsize);
+ PE_READ16(hdr, dh->dh_nblock);
+ PE_READ16(hdr, dh->dh_nreloc);
+ PE_READ16(hdr, dh->dh_hdrsize);
+ PE_READ16(hdr, dh->dh_minalloc);
+ PE_READ16(hdr, dh->dh_maxalloc);
+ PE_READ16(hdr, dh->dh_ss);
+ PE_READ16(hdr, dh->dh_sp);
+ PE_READ16(hdr, dh->dh_checksum);
+ PE_READ16(hdr, dh->dh_ip);
+ PE_READ16(hdr, dh->dh_cs);
+ PE_READ16(hdr, dh->dh_relocpos);
+ PE_READ16(hdr, dh->dh_noverlay);
+
+ /* Do not continue if the EXE is not a PE/NE/... (new executable) */
+ if (dh->dh_relocpos != 0x40) {
+ pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER;
+ return (0);
+ }
+
+ for (i = 0; i < 4; i++)
+ PE_READ16(hdr, dh->dh_reserved1[i]);
+ PE_READ16(hdr, dh->dh_oemid);
+ PE_READ16(hdr, dh->dh_oeminfo);
+ for (i = 0; i < 10; i++)
+ PE_READ16(hdr, dh->dh_reserved2[i]);
+ PE_READ32(hdr, dh->dh_lfanew);
+
+ /* Check if the e_lfanew pointer is valid. */
+ if (dh->dh_lfanew > pe->pe_fsize - 4) {
+ pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER;
+ return (0);
+ }
+
+ if (dh->dh_lfanew < sizeof(PE_DosHdr) &&
+ (pe->pe_flags & LIBPE_F_SPECIAL_FILE)) {
+ pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER;
+ return (0);
+ }
+
+ if (dh->dh_lfanew > sizeof(PE_DosHdr)) {
+ pe->pe_stub_ex = dh->dh_lfanew - sizeof(PE_DosHdr);
+ if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) {
+ /* Read in DOS stub now. */
+ if (libpe_read_msdos_stub(pe) < 0) {
+ pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER;
+ return (0);
+ }
+ }
+ }
+
+ if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) {
+ /* Jump to the PE header. */
+ if (lseek(pe->pe_fd, (off_t) dh->dh_lfanew, SEEK_SET) < 0) {
+ pe->pe_flags |= LIBPE_F_BAD_PE_HEADER;
+ return (0);
+ }
+ }
+
+ if (read(pe->pe_fd, &pe_magic, 4) != 4 ||
+ htole32(pe_magic) != PE_SIGNATURE) {
+ pe->pe_flags |= LIBPE_F_BAD_PE_HEADER;
+ return (0);
+ }
+
+ if (read(pe->pe_fd, coff, sizeof(coff)) != (ssize_t) sizeof(coff)) {
+ pe->pe_flags |= LIBPE_F_BAD_COFF_HEADER;
+ return (0);
+ }
+
+ return (libpe_parse_coff_header(pe, coff));
+}
+
+int
+libpe_read_msdos_stub(PE *pe)
+{
+ void *m;
+
+ assert(pe->pe_stub_ex > 0 &&
+ (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0);
+
+ if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) {
+ if (lseek(pe->pe_fd, (off_t) sizeof(PE_DosHdr), SEEK_SET) <
+ 0) {
+ errno = EIO;
+ goto fail;
+ }
+ }
+
+ if ((m = realloc(pe->pe_stub, sizeof(PE_DosHdr) + pe->pe_stub_ex)) ==
+ NULL) {
+ errno = ENOMEM;
+ goto fail;
+ }
+ pe->pe_stub = m;
+
+ if (read(pe->pe_fd, pe->pe_stub + sizeof(PE_DosHdr), pe->pe_stub_ex) !=
+ (ssize_t) pe->pe_stub_ex) {
+ errno = EIO;
+ goto fail;
+ }
+
+ pe->pe_flags |= LIBPE_F_LOAD_DOS_STUB;
+
+ /* Search for the Rich header embedded just before the PE header. */
+ (void) libpe_parse_rich_header(pe);
+
+ return (0);
+
+fail:
+ pe->pe_stub_ex = 0;
+
+ return (-1);
+}
+
+/*
+ * The "standard" MS-DOS stub displaying "This program cannot be run in
+ * DOS mode".
+ */
+static const char msdos_stub[] = {
+ '\x0e','\x1f','\xba','\x0e','\x00','\xb4','\x09','\xcd',
+ '\x21','\xb8','\x01','\x4c','\xcd','\x21','\x54','\x68',
+ '\x69','\x73','\x20','\x70','\x72','\x6f','\x67','\x72',
+ '\x61','\x6d','\x20','\x63','\x61','\x6e','\x6e','\x6f',
+ '\x74','\x20','\x62','\x65','\x20','\x72','\x75','\x6e',
+ '\x20','\x69','\x6e','\x20','\x44','\x4f','\x53','\x20',
+ '\x6d','\x6f','\x64','\x65','\x2e','\x0d','\x0d','\x0a',
+ '\x24','\x00','\x00','\x00','\x00','\x00','\x00','\x00',
+};
+
+static void
+init_dos_header(PE_DosHdr *dh)
+{
+
+ dh->dh_magic[0] = 'M';
+ dh->dh_magic[1] = 'Z';
+ dh->dh_lastsize = 144;
+ dh->dh_nblock = 3;
+ dh->dh_hdrsize = 4;
+ dh->dh_maxalloc = 65535;
+ dh->dh_sp = 184;
+ dh->dh_relocpos = 0x40;
+ dh->dh_lfanew = 0x80;
+}
+
+off_t
+libpe_write_msdos_stub(PE *pe, off_t off)
+{
+ PE_DosHdr *dh;
+ char tmp[sizeof(PE_DosHdr)], *hdr;
+ off_t d;
+ int i, strip_rich;
+
+ strip_rich = 0;
+
+ if (pe->pe_cmd == PE_C_RDWR) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+
+ if (pe->pe_dh != NULL &&
+ (pe->pe_flags & PE_F_STRIP_DOS_STUB)) {
+ /*
+ * If we strip MS-DOS stub, everything after it
+ * needs rewritten.
+ */
+ pe->pe_flags |= LIBPE_F_BAD_PE_HEADER;
+ goto done;
+ }
+
+ /*
+ * lseek(2) to the PE signature if MS-DOS stub is not
+ * modified.
+ */
+ if (pe->pe_dh != NULL &&
+ (pe->pe_flags & LIBPE_F_DIRTY_DOS_HEADER) == 0 &&
+ (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) == 0 &&
+ (pe->pe_flags & PE_F_STRIP_RICH_HEADER) == 0) {
+ if (lseek(pe->pe_fd,
+ (off_t) (sizeof(PE_DosHdr) + pe->pe_stub_ex),
+ SEEK_CUR) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ off = sizeof(PE_DosHdr) + pe->pe_stub_ex;
+ goto done;
+ }
+
+ /* Check if we should strip the Rich header. */
+ if (pe->pe_dh != NULL && pe->pe_stub_app == NULL &&
+ (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) == 0 &&
+ (pe->pe_flags & PE_F_STRIP_RICH_HEADER)) {
+ if ((pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) {
+ (void) libpe_read_msdos_stub(pe);
+ if (lseek(pe->pe_fd, off, SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+ if (pe->pe_rh != NULL) {
+ strip_rich = 1;
+ pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER;
+ }
+ }
+
+ /*
+ * If length of MS-DOS stub will change, Mark the PE
+ * signature is broken so that the PE signature and the
+ * headers follow it will be rewritten.
+ *
+ * The sections should be loaded now since the stub might
+ * overwrite the section data.
+ */
+ if ((pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) ||
+ (pe->pe_stub_app != NULL && pe->pe_stub_app_sz !=
+ sizeof(PE_DosHdr) + pe->pe_stub_ex) || strip_rich) {
+ if (libpe_load_all_sections(pe) < 0)
+ return (-1);
+ if (lseek(pe->pe_fd, off, SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ pe->pe_flags |= LIBPE_F_BAD_PE_HEADER;
+ }
+ }
+
+ if (pe->pe_flags & PE_F_STRIP_DOS_STUB)
+ goto done;
+
+ /* Always use application supplied MS-DOS stub, if exists. */
+ if (pe->pe_stub_app != NULL && pe->pe_stub_app_sz > 0) {
+ if (write(pe->pe_fd, pe->pe_stub_app, pe->pe_stub_app_sz) !=
+ (ssize_t) pe->pe_stub_app_sz) {
+ errno = EIO;
+ return (-1);
+ }
+ off = pe->pe_stub_app_sz;
+ goto done;
+ }
+
+ /*
+ * Write MS-DOS header.
+ */
+
+ if (pe->pe_dh == NULL) {
+ if ((dh = calloc(1, sizeof(PE_DosHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ pe->pe_dh = dh;
+
+ init_dos_header(dh);
+
+ pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER;
+ } else
+ dh = pe->pe_dh;
+
+ if (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER)
+ init_dos_header(dh);
+
+ if (strip_rich) {
+ d = pe->pe_rh_start - pe->pe_stub;
+ dh->dh_lfanew = roundup(d, 8);
+ }
+
+ if ((pe->pe_flags & LIBPE_F_DIRTY_DOS_HEADER) ||
+ (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER)) {
+ memcpy(tmp, dh->dh_magic, 2);
+ hdr = tmp + 2;
+ PE_WRITE16(hdr, dh->dh_lastsize);
+ PE_WRITE16(hdr, dh->dh_nblock);
+ PE_WRITE16(hdr, dh->dh_nreloc);
+ PE_WRITE16(hdr, dh->dh_hdrsize);
+ PE_WRITE16(hdr, dh->dh_minalloc);
+ PE_WRITE16(hdr, dh->dh_maxalloc);
+ PE_WRITE16(hdr, dh->dh_ss);
+ PE_WRITE16(hdr, dh->dh_sp);
+ PE_WRITE16(hdr, dh->dh_checksum);
+ PE_WRITE16(hdr, dh->dh_ip);
+ PE_WRITE16(hdr, dh->dh_cs);
+ PE_WRITE16(hdr, dh->dh_relocpos);
+ PE_WRITE16(hdr, dh->dh_noverlay);
+ for (i = 0; i < 4; i++)
+ PE_WRITE16(hdr, dh->dh_reserved1[i]);
+ PE_WRITE16(hdr, dh->dh_oemid);
+ PE_WRITE16(hdr, dh->dh_oeminfo);
+ for (i = 0; i < 10; i++)
+ PE_WRITE16(hdr, dh->dh_reserved2[i]);
+ PE_WRITE32(hdr, dh->dh_lfanew);
+
+ if (write(pe->pe_fd, tmp, sizeof(tmp)) !=
+ (ssize_t) sizeof(tmp)) {
+ errno = EIO;
+ return (-1);
+ }
+ } else {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+ if (lseek(pe->pe_fd, (off_t) sizeof(PE_DosHdr), SEEK_CUR) <
+ 0) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+ off = sizeof(PE_DosHdr);
+
+ /*
+ * Write the MS-DOS stub.
+ */
+
+ if (strip_rich) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+ assert(pe->pe_stub != NULL && pe->pe_rh_start != NULL);
+ d = pe->pe_rh_start - pe->pe_stub;
+ if (lseek(pe->pe_fd, d, SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ off = d;
+ goto done;
+ }
+
+ if (pe->pe_cmd == PE_C_RDWR) {
+ if (lseek(pe->pe_fd, (off_t) pe->pe_stub_ex, SEEK_CUR) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ off += pe->pe_stub_ex;
+ goto done;
+ }
+
+ if (write(pe->pe_fd, msdos_stub, sizeof(msdos_stub)) !=
+ (ssize_t) sizeof(msdos_stub)) {
+ errno = EIO;
+ return (-1);
+ }
+ off += sizeof(msdos_stub);
+
+done:
+ pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER;
+ pe->pe_flags &= ~LIBPE_F_BAD_DOS_HEADER;
+
+ return (off);
+}
diff --git a/contrib/elftoolchain/libpe/libpe_init.c b/contrib/elftoolchain/libpe/libpe_init.c
new file mode 100644
index 0000000..2579774
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_init.c
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/stat.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_init.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+int
+libpe_open_object(PE *pe)
+{
+ struct stat sb;
+ mode_t mode;
+ char magic[sizeof(PE_DosHdr)];
+
+ if (fstat(pe->pe_fd, &sb) < 0)
+ return (-1);
+
+ mode = sb.st_mode;
+ pe->pe_fsize = (size_t) sb.st_size;
+
+ /* Reject unsupported file types. */
+ if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) &&
+ !S_ISSOCK(mode)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* Read/Write mode is not supported for non-regular file. */
+ if (pe->pe_cmd == PE_C_RDWR && !S_ISREG(mode)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* The minimal file should at least contain a COFF header. */
+ if (S_ISREG(mode) && pe->pe_fsize < sizeof(PE_CoffHdr)) {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ /*
+ * Search for MS-DOS header or COFF header.
+ */
+
+ if (read(pe->pe_fd, magic, 2) != 2) {
+ errno = EIO;
+ return (-1);
+ }
+
+ if (magic[0] == 'M' && magic[1] == 'Z') {
+ pe->pe_obj = PE_O_PE32;
+ if (read(pe->pe_fd, &magic[2], sizeof(PE_DosHdr) - 2) !=
+ (ssize_t) sizeof(PE_DosHdr) - 2) {
+ errno = EIO;
+ return (-1);
+ }
+ return (libpe_parse_msdos_header(pe, magic));
+
+ } else if (magic[0] == 'P' && magic[1] == 'E') {
+ if (read(pe->pe_fd, magic, 2) != 2) {
+ errno = EIO;
+ return (-1);
+ }
+ if (magic[0] == '\0' && magic[1] == '\0') {
+ pe->pe_obj = PE_O_PE32;
+ if (read(pe->pe_fd, magic, sizeof(PE_CoffHdr)) !=
+ (ssize_t) sizeof(PE_CoffHdr)) {
+ errno = EIO;
+ return (-1);
+ }
+ return (libpe_parse_coff_header(pe, magic));
+ }
+ errno = ENOENT;
+ return (-1);
+
+ } else {
+ pe->pe_obj = PE_O_COFF;
+ if (read(pe->pe_fd, &magic[2], sizeof(PE_CoffHdr) - 2) !=
+ (ssize_t) sizeof(PE_CoffHdr) - 2) {
+ errno = EIO;
+ return (-1);
+ }
+ return (libpe_parse_coff_header(pe, magic));
+ }
+}
+
+void
+libpe_release_object(PE *pe)
+{
+ PE_Scn *ps, *_ps;
+
+ if (pe->pe_dh)
+ free(pe->pe_dh);
+
+ if (pe->pe_rh) {
+ free(pe->pe_rh->rh_compid);
+ free(pe->pe_rh->rh_cnt);
+ free(pe->pe_rh);
+ }
+
+ if (pe->pe_ch)
+ free(pe->pe_ch);
+
+ if (pe->pe_oh)
+ free(pe->pe_oh);
+
+ if (pe->pe_dd)
+ free(pe->pe_dd);
+
+ if (pe->pe_stub)
+ free(pe->pe_stub);
+
+ STAILQ_FOREACH_SAFE(ps, &pe->pe_scn, ps_next, _ps)
+ libpe_release_scn(ps);
+
+ free(pe);
+}
diff --git a/contrib/elftoolchain/libpe/libpe_rich.c b/contrib/elftoolchain/libpe/libpe_rich.c
new file mode 100644
index 0000000..4669a22
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_rich.c
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_rich.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+static char *
+memfind(char *s, const char *find, size_t slen, size_t flen)
+{
+ int i;
+
+ if (slen == 0 || flen == 0 || flen > slen)
+ return (NULL);
+
+ for (i = 0; (size_t) i <= slen - flen; i++) {
+ if (s[i] != find[0])
+ continue;
+ if (flen == 1)
+ return (&s[i]);
+ if (memcmp(&s[i + 1], &find[1], flen - 1) == 0)
+ return (&s[i]);
+ }
+
+ return (NULL);
+}
+
+int
+libpe_parse_rich_header(PE *pe)
+{
+ PE_RichHdr *rh;
+ char *p, *r, *s;
+ uint32_t x;
+ int found, i;
+
+ assert(pe->pe_stub != NULL && pe->pe_stub_ex > 0);
+
+ /* Search for the "Rich" keyword to locate the Rich header. */
+ s = pe->pe_stub + sizeof(PE_DosHdr);
+ r = memfind(s, PE_RICH_TEXT, pe->pe_stub_ex, 4);
+ if (r == NULL || r + 8 > s + pe->pe_stub_ex) {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ if ((rh = calloc(1, sizeof(*rh))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ rh->rh_xor = le32dec(r + 4); /* Retrieve the "XOR mask" */
+
+ /*
+ * Search for the hidden keyword "DanS" by XOR the dwords before
+ * the "Rich" keyword with the XOR mask.
+ */
+ found = 0;
+ for (p = r - 4; p >= s; p -= 4) {
+ x = le32dec(p) ^ rh->rh_xor;
+ if (x == PE_RICH_HIDDEN) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ free(rh);
+ errno = ENOENT;
+ return (-1);
+ }
+
+ /*
+ * Found the "DanS" keyword, which is the start of the Rich header.
+ * The next step is to skip the first 16 bytes (DanS, XOR mask,
+ * XOR mask, XOR mask) and read the (compid,cnt) tuples.
+ */
+ pe->pe_rh_start = p;
+ p += 16;
+ rh->rh_total = (r - p) / 8;
+ if ((rh->rh_compid = malloc(rh->rh_total * sizeof(*rh->rh_compid))) ==
+ NULL) {
+ free(rh);
+ errno = ENOMEM;
+ return (-1);
+ }
+ if ((rh->rh_cnt = malloc(rh->rh_total * sizeof(*rh->rh_cnt))) ==
+ NULL) {
+ free(rh->rh_compid);
+ free(rh);
+ errno = ENOMEM;
+ return (-1);
+ }
+ for (i = 0; (uint32_t) i < rh->rh_total; i++, p += 8) {
+ rh->rh_compid[i] = le32dec(p) ^ rh->rh_xor;
+ rh->rh_cnt[i] = le32dec(p + 4) ^ rh->rh_xor;
+ }
+
+ pe->pe_rh = rh;
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/libpe_section.c b/contrib/elftoolchain/libpe/libpe_section.c
new file mode 100644
index 0000000..7ff63fb
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_section.c
@@ -0,0 +1,518 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_Scn *
+libpe_alloc_scn(PE *pe)
+{
+ PE_Scn *ps;
+
+ if ((ps = calloc(1, sizeof(PE_Scn))) == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ STAILQ_INIT(&ps->ps_b);
+ ps->ps_pe = pe;
+
+ return (ps);
+}
+
+void
+libpe_release_scn(PE_Scn *ps)
+{
+ PE *pe;
+ PE_SecBuf *sb, *_sb;
+
+ assert(ps != NULL);
+
+ pe = ps->ps_pe;
+
+ STAILQ_REMOVE(&pe->pe_scn, ps, _PE_Scn, ps_next);
+
+ STAILQ_FOREACH_SAFE(sb, &ps->ps_b, sb_next, _sb)
+ libpe_release_buffer(sb);
+
+ free(ps);
+}
+
+static int
+cmp_scn(PE_Scn *a, PE_Scn *b)
+{
+
+ if (a->ps_sh.sh_addr < b->ps_sh.sh_addr)
+ return (-1);
+ else if (a->ps_sh.sh_addr == b->ps_sh.sh_addr)
+ return (0);
+ else
+ return (1);
+}
+
+static void
+sort_sections(PE *pe)
+{
+
+ if (STAILQ_EMPTY(&pe->pe_scn))
+ return;
+
+ /* Sort the list of Scn by RVA in ascending order. */
+ STAILQ_SORT(&pe->pe_scn, _PE_Scn, ps_next, cmp_scn);
+}
+
+int
+libpe_parse_section_headers(PE *pe)
+{
+ char tmp[sizeof(PE_SecHdr)], *hdr;
+ PE_Scn *ps;
+ PE_SecHdr *sh;
+ PE_CoffHdr *ch;
+ PE_DataDir *dd;
+ int found, i;
+
+ assert(pe->pe_ch != NULL);
+
+ for (i = 0; (uint16_t) i < pe->pe_ch->ch_nsec; i++) {
+ if (read(pe->pe_fd, tmp, sizeof(PE_SecHdr)) !=
+ (ssize_t) sizeof(PE_SecHdr)) {
+ pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER;
+ return (0);
+ }
+
+ if ((ps = libpe_alloc_scn(pe)) == NULL)
+ return (-1);
+ STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
+ ps->ps_ndx = ++pe->pe_nscn; /* Setion index is 1-based */
+ sh = &ps->ps_sh;
+
+ /*
+ * Note that the section name won't be NUL-terminated if
+ * its length happens to be 8.
+ */
+ memcpy(sh->sh_name, tmp, sizeof(sh->sh_name));
+ hdr = tmp + 8;
+ PE_READ32(hdr, sh->sh_virtsize);
+ PE_READ32(hdr, sh->sh_addr);
+ PE_READ32(hdr, sh->sh_rawsize);
+ PE_READ32(hdr, sh->sh_rawptr);
+ PE_READ32(hdr, sh->sh_relocptr);
+ PE_READ32(hdr, sh->sh_lineptr);
+ PE_READ16(hdr, sh->sh_nreloc);
+ PE_READ16(hdr, sh->sh_nline);
+ PE_READ32(hdr, sh->sh_char);
+ }
+
+ /*
+ * For all the data directories that don't belong to any section,
+ * we create pseudo sections for them to make layout easier.
+ */
+ dd = pe->pe_dd;
+ if (dd != NULL && dd->dd_total > 0) {
+ for (i = 0; (uint32_t) i < pe->pe_dd->dd_total; i++) {
+ if (dd->dd_e[i].de_size == 0)
+ continue;
+ found = 0;
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ sh = &ps->ps_sh;
+ if (dd->dd_e[i].de_addr >= sh->sh_addr &&
+ dd->dd_e[i].de_addr + dd->dd_e[i].de_size <=
+ sh->sh_addr + sh->sh_virtsize) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ if ((ps = libpe_alloc_scn(pe)) == NULL)
+ return (-1);
+ STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
+ ps->ps_ndx = 0xFFFF0000U | i;
+ sh = &ps->ps_sh;
+ sh->sh_rawptr = dd->dd_e[i].de_addr; /* FIXME */
+ sh->sh_rawsize = dd->dd_e[i].de_size;
+ }
+ }
+
+ /*
+ * Also consider the COFF symbol table as a pseudo section.
+ */
+ ch = pe->pe_ch;
+ if (ch->ch_nsym > 0) {
+ if ((ps = libpe_alloc_scn(pe)) == NULL)
+ return (-1);
+ STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
+ ps->ps_ndx = 0xFFFFFFFFU;
+ sh = &ps->ps_sh;
+ sh->sh_rawptr = ch->ch_symptr;
+ sh->sh_rawsize = ch->ch_nsym * PE_SYM_ENTRY_SIZE;
+ pe->pe_nsym = ch->ch_nsym;
+ }
+
+ /* PE file headers initialization is complete if we reach here. */
+ return (0);
+}
+
+int
+libpe_load_section(PE *pe, PE_Scn *ps)
+{
+ PE_SecHdr *sh;
+ PE_SecBuf *sb;
+ size_t sz;
+ char tmp[4];
+
+ assert(pe != NULL && ps != NULL);
+ assert((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0);
+
+ sh = &ps->ps_sh;
+
+ /* Allocate a PE_SecBuf struct without buffer for empty sections. */
+ if (sh->sh_rawsize == 0) {
+ (void) libpe_alloc_buffer(ps, 0);
+ ps->ps_flags |= LIBPE_F_LOAD_SECTION;
+ return (0);
+ }
+
+ if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) {
+ if (lseek(pe->pe_fd, (off_t) sh->sh_rawptr, SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+ if ((sb = libpe_alloc_buffer(ps, sh->sh_rawsize)) == NULL)
+ return (-1);
+
+ if (read(pe->pe_fd, sb->sb_pb.pb_buf, sh->sh_rawsize) !=
+ (ssize_t) sh->sh_rawsize) {
+ errno = EIO;
+ return (-1);
+ }
+
+ if (ps->ps_ndx == 0xFFFFFFFFU) {
+ /*
+ * Index 0xFFFFFFFF indicates this section is a pseudo
+ * section that contains the COFF symbol table. We should
+ * read in the string table right after it.
+ */
+ if (read(pe->pe_fd, tmp, sizeof(tmp)) !=
+ (ssize_t) sizeof(tmp)) {
+ errno = EIO;
+ return (-1);
+ }
+ sz = le32dec(tmp);
+
+ /*
+ * The minimum value for the size field is 4, which indicates
+ * there is no string table.
+ */
+ if (sz > 4) {
+ sz -= 4;
+ if ((sb = libpe_alloc_buffer(ps, sz)) == NULL)
+ return (-1);
+ if (read(pe->pe_fd, sb->sb_pb.pb_buf, sz) !=
+ (ssize_t) sz) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+ }
+
+ ps->ps_flags |= LIBPE_F_LOAD_SECTION;
+
+ return (0);
+}
+
+int
+libpe_load_all_sections(PE *pe)
+{
+ PE_Scn *ps;
+ PE_SecHdr *sh;
+ unsigned r, s;
+ off_t off;
+ char tmp[256];
+
+ /* Calculate the current offset into the file. */
+ off = 0;
+ if (pe->pe_dh != NULL)
+ off += pe->pe_dh->dh_lfanew + 4;
+ if (pe->pe_ch != NULL)
+ off += sizeof(PE_CoffHdr) + pe->pe_ch->ch_optsize;
+
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ if (ps->ps_flags & LIBPE_F_LOAD_SECTION)
+ continue;
+ sh = &ps->ps_sh;
+
+ /*
+ * For special files, we consume the padding in between
+ * and advance to the section offset.
+ */
+ if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) {
+ /* Can't go backwards. */
+ if (off > sh->sh_rawptr) {
+ errno = EIO;
+ return (-1);
+ }
+ if (off < sh->sh_rawptr) {
+ r = sh->sh_rawptr - off;
+ for (; r > 0; r -= s) {
+ s = r > sizeof(tmp) ? sizeof(tmp) : r;
+ if (read(pe->pe_fd, tmp, s) !=
+ (ssize_t) s) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+ }
+ }
+
+ /* Load the section content. */
+ if (libpe_load_section(pe, ps) < 0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+libpe_resync_sections(PE *pe, off_t off)
+{
+ PE_Scn *ps;
+ PE_SecHdr *sh;
+ size_t falign, nsec;
+
+ /* Firstly, sort all sections by their file offsets. */
+ sort_sections(pe);
+
+ /* Count the number of sections. */
+ nsec = 0;
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ if (ps->ps_flags & LIBPE_F_STRIP_SECTION)
+ continue;
+ if (ps->ps_ndx & 0xFFFF0000U)
+ continue;
+ nsec++;
+ }
+ pe->pe_nscn = nsec;
+
+ /*
+ * Calculate the file offset for the first section. (`off' is
+ * currently pointing to the COFF header.)
+ */
+ off += sizeof(PE_CoffHdr);
+ if (pe->pe_ch != NULL && pe->pe_ch->ch_optsize > 0)
+ off += pe->pe_ch->ch_optsize;
+ else {
+ switch (pe->pe_obj) {
+ case PE_O_PE32:
+ off += PE_COFF_OPT_SIZE_32;
+ break;
+ case PE_O_PE32P:
+ off += PE_COFF_OPT_SIZE_32P;
+ break;
+ case PE_O_COFF:
+ default:
+ break;
+ }
+ }
+ off += nsec * sizeof(PE_SecHdr);
+
+ /*
+ * Determine the file alignment for sections.
+ */
+ if (pe->pe_oh != NULL && pe->pe_oh->oh_filealign > 0)
+ falign = pe->pe_oh->oh_filealign;
+ else {
+ /*
+ * Use the default file alignment defined by the
+ * PE/COFF specification.
+ */
+ if (pe->pe_obj == PE_O_COFF)
+ falign = 4;
+ else
+ falign = 512;
+ }
+
+ /*
+ * Step through each section (and pseduo section) and verify
+ * alignment constraint and overlapping, make adjustment if need.
+ */
+ pe->pe_rvamax = 0;
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ if (ps->ps_flags & LIBPE_F_STRIP_SECTION)
+ continue;
+
+ sh = &ps->ps_sh;
+
+ if (sh->sh_addr + sh->sh_virtsize > pe->pe_rvamax)
+ pe->pe_rvamax = sh->sh_addr + sh->sh_virtsize;
+
+ if (ps->ps_ndx & 0xFFFF0000U)
+ ps->ps_falign = 4;
+ else
+ ps->ps_falign = falign;
+
+ off = roundup(off, ps->ps_falign);
+
+ if (off != sh->sh_rawptr)
+ ps->ps_flags |= PE_F_DIRTY;
+
+ if (ps->ps_flags & PE_F_DIRTY) {
+ if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) {
+ if (libpe_load_section(pe, ps) < 0)
+ return (-1);
+ }
+ sh->sh_rawsize = libpe_resync_buffers(ps);
+ }
+
+ /*
+ * Sections only contains uninitialized data should set
+ * PointerToRawData to zero according to the PE/COFF
+ * specification.
+ */
+ if (sh->sh_rawsize == 0)
+ sh->sh_rawptr = 0;
+ else
+ sh->sh_rawptr = off;
+
+ off += sh->sh_rawsize;
+ }
+
+ return (0);
+}
+
+off_t
+libpe_write_section_headers(PE *pe, off_t off)
+{
+ char tmp[sizeof(PE_SecHdr)], *hdr;
+ PE_Scn *ps;
+ PE_SecHdr *sh;
+
+ if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER || pe->pe_nscn == 0)
+ return (off);
+
+ if ((pe->pe_flags & LIBPE_F_DIRTY_SEC_HEADER) == 0) {
+ off += sizeof(PE_SecHdr) * pe->pe_ch->ch_nsec;
+ return (off);
+ }
+
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ if (ps->ps_flags & LIBPE_F_STRIP_SECTION)
+ continue;
+ if (ps->ps_ndx & 0xFFFF0000U)
+ continue;
+ if ((pe->pe_flags & LIBPE_F_DIRTY_SEC_HEADER) == 0 &&
+ (ps->ps_flags & PE_F_DIRTY) == 0)
+ goto next_header;
+
+ sh = &ps->ps_sh;
+
+ memcpy(tmp, sh->sh_name, sizeof(sh->sh_name));
+ hdr = tmp + 8;
+ PE_WRITE32(hdr, sh->sh_virtsize);
+ PE_WRITE32(hdr, sh->sh_addr);
+ PE_WRITE32(hdr, sh->sh_rawsize);
+ PE_WRITE32(hdr, sh->sh_rawptr);
+ PE_WRITE32(hdr, sh->sh_relocptr);
+ PE_WRITE32(hdr, sh->sh_lineptr);
+ PE_WRITE16(hdr, sh->sh_nreloc);
+ PE_WRITE16(hdr, sh->sh_nline);
+ PE_WRITE32(hdr, sh->sh_char);
+
+ if (write(pe->pe_fd, tmp, sizeof(PE_SecHdr)) !=
+ (ssize_t) sizeof(PE_SecHdr)) {
+ errno = EIO;
+ return (-1);
+ }
+
+ next_header:
+ off += sizeof(PE_SecHdr);
+ }
+
+ return (off);
+}
+
+off_t
+libpe_write_sections(PE *pe, off_t off)
+{
+ PE_Scn *ps;
+ PE_SecHdr *sh;
+
+ if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER)
+ return (off);
+
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ sh = &ps->ps_sh;
+
+ if (ps->ps_flags & LIBPE_F_STRIP_SECTION)
+ continue;
+
+ /* Skip empty sections. */
+ if (sh->sh_rawptr == 0 || sh->sh_rawsize == 0)
+ continue;
+
+ /*
+ * Padding between sections. (padding always written
+ * in case the the section headers or sections are
+ * moved or shrinked.)
+ */
+ assert(off <= sh->sh_rawptr);
+ if (off < sh->sh_rawptr)
+ libpe_pad(pe, sh->sh_rawptr - off);
+
+ if ((ps->ps_flags & PE_F_DIRTY) == 0) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+ if (lseek(pe->pe_fd,
+ (off_t) (sh->sh_rawptr + sh->sh_rawsize),
+ SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ off = sh->sh_rawptr + sh->sh_rawsize;
+ continue;
+ }
+
+ off = sh->sh_rawptr;
+
+ if (libpe_write_buffers(ps) < 0)
+ return (-1);
+
+ off += sh->sh_rawsize;
+
+ ps->ps_flags &= ~PE_F_DIRTY;
+ }
+
+ return (off);
+}
diff --git a/contrib/elftoolchain/libpe/libpe_utils.c b/contrib/elftoolchain/libpe/libpe_utils.c
new file mode 100644
index 0000000..9bc9a54
--- /dev/null
+++ b/contrib/elftoolchain/libpe/libpe_utils.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: libpe_utils.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+off_t
+libpe_align(PE *pe, off_t off, size_t align)
+{
+ off_t n;
+
+ assert(align > 0 && (align & (align - 1)) == 0);
+
+ n = roundup(off, align);
+ if (n > off) {
+ if (libpe_pad(pe, n - off) < 0)
+ return (-1);
+ }
+
+ return (n);
+}
+
+int
+libpe_pad(PE *pe, size_t pad)
+{
+ char tmp[128];
+ size_t s;
+
+ memset(tmp, 0, sizeof(tmp));
+ for (; pad > 0; pad -= s) {
+ s = pad > sizeof(tmp) ? sizeof(tmp) : pad;
+ if (write(pe->pe_fd, tmp, s) != (ssize_t) s) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/os.Linux.mk b/contrib/elftoolchain/libpe/os.Linux.mk
new file mode 100644
index 0000000..ed5bdf0
--- /dev/null
+++ b/contrib/elftoolchain/libpe/os.Linux.mk
@@ -0,0 +1,6 @@
+# $Id: os.Linux.mk 3312 2016-01-10 09:23:51Z kaiwang27 $
+
+CFLAGS+= -Wall -Wno-unused-parameter -Wstrict-prototypes \
+ -Wmissing-prototypes -Wpointer-arith -Wreturn-type \
+ -Wcast-qual -Wwrite-strings -Wswitch -Wshadow \
+ -Wcast-align -Wunused-parameter
diff --git a/contrib/elftoolchain/libpe/os.NetBSD.mk b/contrib/elftoolchain/libpe/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/libpe/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/libpe/pe.h b/contrib/elftoolchain/libpe/pe.h
new file mode 100644
index 0000000..5b6130e
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe.h
@@ -0,0 +1,292 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: pe.h 3312 2016-01-10 09:23:51Z kaiwang27 $
+ */
+
+#ifndef _PE_H_
+#define _PE_H_
+
+#include <stdint.h>
+
+/*
+ * MS-DOS header.
+ */
+
+typedef struct _PE_DosHdr {
+ char dh_magic[2];
+ uint16_t dh_lastsize;
+ uint16_t dh_nblock;
+ uint16_t dh_nreloc;
+ uint16_t dh_hdrsize;
+ uint16_t dh_minalloc;
+ uint16_t dh_maxalloc;
+ uint16_t dh_ss;
+ uint16_t dh_sp;
+ uint16_t dh_checksum;
+ uint16_t dh_ip;
+ uint16_t dh_cs;
+ uint16_t dh_relocpos;
+ uint16_t dh_noverlay;
+ uint16_t dh_reserved1[4];
+ uint16_t dh_oemid;
+ uint16_t dh_oeminfo;
+ uint16_t dh_reserved2[10];
+ uint32_t dh_lfanew;
+} PE_DosHdr;
+
+/*
+ * Rich header.
+ */
+
+typedef struct _PE_RichHdr {
+ uint32_t rh_xor;
+ uint32_t rh_total;
+ uint32_t *rh_compid;
+ uint32_t *rh_cnt;
+} PE_RichHdr;
+
+/*
+ * COFF header: Machine Types.
+ */
+
+#define IMAGE_FILE_MACHINE_UNKNOWN 0x0 /* not specified */
+#define IMAGE_FILE_MACHINE_AM33 0x1d3 /* Matsushita AM33 */
+#define IMAGE_FILE_MACHINE_AMD64 0x8664 /* x86-64 */
+#define IMAGE_FILE_MACHINE_ARM 0x1c0 /* ARM LE */
+#define IMAGE_FILE_MACHINE_ARMNT 0x1c4 /* ARMv7(or higher) Thumb */
+#define IMAGE_FILE_MACHINE_ARM64 0xaa64 /* ARMv8 64-bit */
+#define IMAGE_FILE_MACHINE_EBC 0xebc /* EFI byte code */
+#define IMAGE_FILE_MACHINE_I386 0x14c /* x86 */
+#define IMAGE_FILE_MACHINE_IA64 0x200 /* IA64 */
+#define IMAGE_FILE_MACHINE_M32R 0x9041 /* Mitsubishi M32R LE */
+#define IMAGE_FILE_MACHINE_MIPS16 0x266 /* MIPS16 */
+#define IMAGE_FILE_MACHINE_MIPSFPU 0x366 /* MIPS with FPU */
+#define IMAGE_FILE_MACHINE_MIPSFPU16 0x466 /* MIPS16 with FPU */
+#define IMAGE_FILE_MACHINE_POWERPC 0x1f0 /* Power PC LE */
+#define IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 /* Power PC floating point */
+#define IMAGE_FILE_MACHINE_R4000 0x166 /* MIPS R4000 LE */
+#define IMAGE_FILE_MACHINE_SH3 0x1a2 /* Hitachi SH3 */
+#define IMAGE_FILE_MACHINE_SH3DSP 0x1a3 /* Hitachi SH3 DSP */
+#define IMAGE_FILE_MACHINE_SH4 0x1a6 /* Hitachi SH4 */
+#define IMAGE_FILE_MACHINE_SH5 0x1a8 /* Hitachi SH5 */
+#define IMAGE_FILE_MACHINE_THUMB 0x1c2 /* ARM or Thumb interworking */
+#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x169 /* MIPS LE WCE v2 */
+
+/*
+ * COFF header: Characteristics
+ */
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
+#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+/*
+ * COFF Header.
+ */
+
+typedef struct _PE_CoffHdr {
+ uint16_t ch_machine;
+ uint16_t ch_nsec;
+ uint32_t ch_timestamp;
+ uint32_t ch_symptr;
+ uint32_t ch_nsym;
+ uint16_t ch_optsize;
+ uint16_t ch_char;
+} PE_CoffHdr;
+
+
+/*
+ * Optional Header: Subsystem.
+ */
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0
+#define IMAGE_SUBSYSTEM_NATIVE 1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7
+#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9
+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#define IMAGE_SUBSYSTEM_EFI_ROM 13
+#define IMAGE_SUBSYSTEM_XBOX 14
+
+/*
+ * Optional Header: DLL Characteristics
+ */
+
+#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE 0x0040
+#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY 0x0080
+#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT 0x0100
+#define IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION 0x0200
+#define IMAGE_DLL_CHARACTERISTICS_NO_SEH 0x0400
+#define IMAGE_DLL_CHARACTERISTICS_NO_BIND 0x0800
+#define IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER 0x2000
+#define IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
+
+/*
+ * Optional Header.
+ */
+
+#define PE_FORMAT_ROM 0x107
+#define PE_FORMAT_32 0x10b
+#define PE_FORMAT_32P 0x20b
+
+typedef struct _PE_OptHdr {
+ uint16_t oh_magic;
+ uint8_t oh_ldvermajor;
+ uint8_t oh_ldverminor;
+ uint32_t oh_textsize;
+ uint32_t oh_datasize;
+ uint32_t oh_bsssize;
+ uint32_t oh_entry;
+ uint32_t oh_textbase;
+ uint32_t oh_database;
+ uint64_t oh_imgbase;
+ uint32_t oh_secalign;
+ uint32_t oh_filealign;
+ uint16_t oh_osvermajor;
+ uint16_t oh_osverminor;
+ uint16_t oh_imgvermajor;
+ uint16_t oh_imgverminor;
+ uint16_t oh_subvermajor;
+ uint16_t oh_subverminor;
+ uint32_t oh_win32ver;
+ uint32_t oh_imgsize;
+ uint32_t oh_hdrsize;
+ uint32_t oh_checksum;
+ uint16_t oh_subsystem;
+ uint16_t oh_dllchar;
+ uint64_t oh_stacksizer;
+ uint64_t oh_stacksizec;
+ uint64_t oh_heapsizer;
+ uint64_t oh_heapsizec;
+ uint32_t oh_ldrflags;
+ uint32_t oh_ndatadir;
+} PE_OptHdr;
+
+/*
+ * Optional Header: Data Directories.
+ */
+
+#define PE_DD_EXPORT 0
+#define PE_DD_IMPORT 1
+#define PE_DD_RESROUCE 2
+#define PE_DD_EXCEPTION 3
+#define PE_DD_CERTIFICATE 4
+#define PE_DD_BASERELOC 5
+#define PE_DD_DEBUG 6
+#define PE_DD_ARCH 7
+#define PE_DD_GLOBALPTR 8
+#define PE_DD_TLS 9
+#define PE_DD_LOADCONFIG 10
+#define PE_DD_BOUNDIMPORT 11
+#define PE_DD_IAT 12
+#define PE_DD_DELAYIMPORT 13
+#define PE_DD_CLRRUNTIME 14
+#define PE_DD_RESERVED 15
+#define PE_DD_MAX 16
+
+typedef struct _PE_DataDirEntry {
+ uint32_t de_addr;
+ uint32_t de_size;
+} PE_DataDirEntry;
+
+typedef struct _PE_DataDir {
+ PE_DataDirEntry dd_e[PE_DD_MAX];
+ uint32_t dd_total;
+} PE_DataDir;
+
+/*
+ * Section Headers: Section flags.
+ */
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+#define IMAGE_SCN_LNK_OTHER 0x00000100
+#define IMAGE_SCN_LNK_INFO 0x00000200
+#define IMAGE_SCN_LNK_REMOVE 0x00000800
+#define IMAGE_SCN_LNK_COMDAT 0x00001000
+#define IMAGE_SCN_GPREL 0x00008000
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
+#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+/*
+ * Section Headers.
+ */
+
+typedef struct _PE_SecHdr {
+ char sh_name[8];
+ uint32_t sh_virtsize;
+ uint32_t sh_addr;
+ uint32_t sh_rawsize;
+ uint32_t sh_rawptr;
+ uint32_t sh_relocptr;
+ uint32_t sh_lineptr;
+ uint16_t sh_nreloc;
+ uint16_t sh_nline;
+ uint32_t sh_char;
+} PE_SecHdr;
+
+#endif /* !_PE_H_ */
diff --git a/contrib/elftoolchain/libpe/pe_buffer.c b/contrib/elftoolchain/libpe/pe_buffer.c
new file mode 100644
index 0000000..e4ac19f
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_buffer.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_buffer.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_Buffer *
+pe_getbuffer(PE_Scn *ps, PE_Buffer *pb)
+{
+ PE *pe;
+ PE_SecBuf *sb;
+
+ if (ps == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ pe = ps->ps_pe;
+
+ if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) {
+ if (pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (NULL);
+ }
+ if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) {
+ if (libpe_load_all_sections(pe) < 0)
+ return (NULL);
+ } else {
+ if (libpe_load_section(pe, ps) < 0)
+ return (NULL);
+ }
+ }
+
+ sb = (PE_SecBuf *) pb;
+
+ if (sb == NULL)
+ sb = STAILQ_FIRST(&ps->ps_b);
+ else
+ sb = STAILQ_NEXT(sb, sb_next);
+
+ return ((PE_Buffer *) sb);
+}
+
+PE_Buffer *
+pe_newbuffer(PE_Scn *ps)
+{
+ PE *pe;
+ PE_SecBuf *sb;
+
+ if (ps == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ pe = ps->ps_pe;
+
+ if (pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (NULL);
+ }
+
+ if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) {
+ if (libpe_load_section(pe, ps) < 0)
+ return (NULL);
+ }
+
+ if ((sb = libpe_alloc_buffer(ps, 0)) == NULL)
+ return (NULL);
+
+ sb->sb_flags |= PE_F_DIRTY;
+ ps->ps_flags |= PE_F_DIRTY;
+
+ return ((PE_Buffer *) sb);
+}
diff --git a/contrib/elftoolchain/libpe/pe_cntl.c b/contrib/elftoolchain/libpe/pe_cntl.c
new file mode 100644
index 0000000..1fc8c47
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_cntl.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_cntl.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+int
+pe_cntl(PE *pe, PE_Cmd cmd)
+{
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ switch (cmd) {
+ case PE_C_FDDONE:
+ pe->pe_flags |= LIBPE_F_FD_DONE;
+ break;
+
+ case PE_C_FDREAD:
+ if (pe->pe_cmd == PE_C_WRITE) {
+ errno = EACCES;
+ return (-1);
+ }
+ if (libpe_load_all_sections(pe) < 0)
+ return (-1);
+ break;
+
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_coff.c b/contrib/elftoolchain/libpe/pe_coff.c
new file mode 100644
index 0000000..d5cd833
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_coff.c
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_coff.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_CoffHdr *
+pe_coff_header(PE *pe)
+{
+
+ if (pe->pe_ch == NULL) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ return (pe->pe_ch);
+}
+
+PE_OptHdr *
+pe_opt_header(PE *pe)
+{
+
+ if (pe->pe_oh == NULL) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ return (pe->pe_oh);
+}
+
+PE_DataDir *
+pe_data_dir(PE *pe)
+{
+
+ if (pe->pe_dd == NULL) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ return (pe->pe_dd);
+}
+
+int
+pe_update_coff_header(PE *pe, PE_CoffHdr *ch)
+{
+
+ if (pe == NULL || ch == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ if (pe->pe_ch == NULL) {
+ if ((pe->pe_ch = malloc(sizeof(PE_CoffHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ } else {
+ /* Rewrite optional header if `optsize' field changed. */
+ if (pe->pe_ch->ch_optsize != ch->ch_optsize)
+ pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER;
+ }
+
+ *pe->pe_ch = *ch;
+
+ pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER;
+
+ return (0);
+}
+
+int
+pe_update_opt_header(PE *pe, PE_OptHdr *oh)
+{
+
+ if (pe == NULL || oh == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ if (pe->pe_oh == NULL) {
+ if ((pe->pe_oh = malloc(sizeof(PE_OptHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ }
+
+ *pe->pe_oh = *oh;
+
+ pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER;
+
+ return (0);
+}
+
+int
+pe_update_data_dir(PE *pe, PE_DataDir *dd)
+{
+
+ if (pe == NULL || dd == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ if (pe->pe_dd == NULL) {
+ if ((pe->pe_dd = malloc(sizeof(PE_DataDir))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ }
+
+ *pe->pe_dd = *dd;
+
+ pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER;
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_dos.c b/contrib/elftoolchain/libpe/pe_dos.c
new file mode 100644
index 0000000..01ba42f
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_dos.c
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_dos.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_DosHdr *
+pe_msdos_header(PE *pe)
+{
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (pe->pe_dh == NULL) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ return (pe->pe_dh);
+}
+
+char *
+pe_msdos_stub(PE *pe, size_t *len)
+{
+
+ if (pe == NULL || len == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (pe->pe_stub_ex > 0 &&
+ (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+ (void) libpe_read_msdos_stub(pe);
+ }
+
+ *len = sizeof(PE_DosHdr) + pe->pe_stub_ex;
+
+ return (pe->pe_stub);
+}
+
+int
+ps_update_msdos_header(PE *pe, PE_DosHdr *dh)
+{
+
+ if (pe == NULL || dh == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ if (pe->pe_dh == NULL) {
+ if ((pe->pe_dh = malloc(sizeof(PE_DosHdr))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ }
+
+ *pe->pe_dh = *dh;
+
+ pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER;
+
+ return (0);
+}
+
+int
+ps_update_msdos_stub(PE *pe, char *dos_stub, size_t sz)
+{
+
+ if (pe == NULL || dos_stub == NULL || sz == 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ pe->pe_stub_app = dos_stub;
+ pe->pe_stub_app_sz = sz;
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_flag.c b/contrib/elftoolchain/libpe/pe_flag.c
new file mode 100644
index 0000000..c392a4d
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_flag.c
@@ -0,0 +1,187 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_flag.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+int
+pe_flag(PE *pe, PE_Cmd c, unsigned int flags)
+{
+
+ if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if ((flags & ~(PE_F_STRIP_DOS_STUB | PE_F_STRIP_RICH_HEADER |
+ PE_F_STRIP_SYMTAB | PE_F_STRIP_DEBUG)) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (c == PE_C_SET)
+ pe->pe_flags |= flags;
+ else
+ pe->pe_flags &= ~flags;
+
+ return (0);
+}
+
+int
+pe_flag_dos_header(PE *pe, PE_Cmd c, unsigned int flags)
+{
+
+ if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~PE_F_DIRTY) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (c == PE_C_SET)
+ pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER;
+ else
+ pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER;
+
+ return (0);
+}
+
+int
+pe_flag_coff_header(PE *pe, PE_Cmd c, unsigned int flags)
+{
+
+ if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~PE_F_DIRTY) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (c == PE_C_SET)
+ pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER;
+ else
+ pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER;
+
+ return (0);
+}
+
+int
+pe_flag_opt_header(PE *pe, PE_Cmd c, unsigned int flags)
+{
+
+ if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~PE_F_DIRTY) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (c == PE_C_SET)
+ pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER;
+ else
+ pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER;
+
+ return (0);
+}
+
+int
+pe_flag_data_dir(PE *pe, PE_Cmd c, unsigned int flags)
+{
+
+ if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~PE_F_DIRTY) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (c == PE_C_SET)
+ pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER;
+ else
+ pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER;
+
+ return (0);
+}
+
+int
+pe_flag_scn(PE_Scn *ps, PE_Cmd c, unsigned int flags)
+{
+
+ if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~(PE_F_DIRTY | PE_F_STRIP_SECTION)) == 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (c == PE_C_SET)
+ ps->ps_flags |= flags;
+ else
+ ps->ps_flags &= ~flags;
+
+ return (0);
+}
+
+int
+pe_flag_section_header(PE_Scn *ps, PE_Cmd c, unsigned int flags)
+{
+ PE *pe;
+
+ if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~PE_F_DIRTY) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ pe = ps->ps_pe;
+
+ /* The library doesn't support per section header dirty flag. */
+ if (c == PE_C_SET)
+ pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
+ else
+ pe->pe_flags &= ~LIBPE_F_DIRTY_SEC_HEADER;
+
+ return (0);
+}
+
+int
+pe_flag_buffer(PE_Buffer *pb, PE_Cmd c, unsigned int flags)
+{
+ PE_SecBuf *sb;
+
+ if (pb == NULL || (c != PE_C_SET && c != PE_C_CLR) ||
+ (flags & ~PE_F_DIRTY) != 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ sb = (PE_SecBuf *) pb;
+
+ if (c == PE_C_SET)
+ sb->sb_flags |= flags;
+ else
+ sb->sb_flags &= ~flags;
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_init.c b/contrib/elftoolchain/libpe/pe_init.c
new file mode 100644
index 0000000..4e2f22a
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_init.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2015 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_init.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE *
+pe_init(int fd, PE_Cmd c, PE_Object o)
+{
+ PE *pe;
+
+ if ((pe = calloc(1, sizeof(*pe))) == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ pe->pe_fd = fd;
+ pe->pe_cmd = c;
+ pe->pe_obj = o;
+ STAILQ_INIT(&pe->pe_scn);
+
+ switch (c) {
+ case PE_C_READ:
+ case PE_C_RDWR:
+ if (libpe_open_object(pe) < 0)
+ goto init_fail;
+ break;
+
+ case PE_C_WRITE:
+ if (o < PE_O_PE32 || o > PE_O_COFF) {
+ errno = EINVAL;
+ goto init_fail;
+ }
+ break;
+
+ default:
+ errno = EINVAL;
+ goto init_fail;
+ }
+
+ return (pe);
+
+init_fail:
+ pe_finish(pe);
+ return (NULL);
+}
+
+void
+pe_finish(PE *pe)
+{
+
+ if (pe == NULL)
+ return;
+
+ libpe_release_object(pe);
+}
+
+PE_Object
+pe_object(PE *pe)
+{
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (PE_O_UNKNOWN);
+ }
+
+ return (pe->pe_obj);
+}
diff --git a/contrib/elftoolchain/libpe/pe_rich.c b/contrib/elftoolchain/libpe/pe_rich.c
new file mode 100644
index 0000000..ea1029e
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_rich.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_rich.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_RichHdr *
+pe_rich_header(PE *pe)
+{
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (pe->pe_rh == NULL && pe->pe_stub_ex > 0 &&
+ (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) {
+ assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0);
+ (void) libpe_read_msdos_stub(pe);
+ }
+
+ if (pe->pe_rh == NULL) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ return (pe->pe_rh);
+}
+
+static uint32_t
+rol32(uint32_t n, int c)
+{
+
+ c &= 0x1f;
+
+ return ((n << c) | (n >> (0x20 - c)));
+}
+
+int
+pe_rich_header_validate(PE *pe)
+{
+ PE_RichHdr *rh;
+ uint32_t cksum;
+ char *p;
+ int i, off;
+
+ if (pe_rich_header(pe) == NULL)
+ return (-1);
+
+ assert(pe->pe_rh_start != NULL);
+
+ /*
+ * Initial value of the checksum is the offset to the begin of
+ * the Rich header.
+ */
+ cksum = pe->pe_rh_start - pe->pe_stub;
+
+ /*
+ * Add the bytes before the Rich header to the checksum, rotated
+ * left by the offset.
+ */
+ for (p = pe->pe_stub; p < pe->pe_rh_start; p++) {
+ /* Skip dh_lfanew. */
+ off = p - pe->pe_stub;
+ if (off >= 0x3c && off < 0x40)
+ continue;
+ cksum += rol32((unsigned char) *p, off);
+ }
+
+ /* Add each compid rotated left by its count to the checksum. */
+ rh = pe->pe_rh;
+ for (i = 0; (uint32_t) i < rh->rh_total; i++)
+ cksum += rol32(rh->rh_compid[i], rh->rh_cnt[i]);
+
+ /* Validate the checksum with the XOR mask stored after "Rich". */
+ if (cksum == rh->rh_xor)
+ return (1);
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_section.c b/contrib/elftoolchain/libpe/pe_section.c
new file mode 100644
index 0000000..3e82d84
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_section.c
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+PE_Scn *
+pe_getscn(PE *pe, size_t ndx)
+{
+ PE_Scn *ps;
+
+ if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ if (ps->ps_ndx == ndx)
+ return (ps);
+ }
+
+ errno = ENOENT;
+
+ return (NULL);
+}
+
+size_t
+pe_ndxscn(PE_Scn *ps)
+{
+
+ if (ps == NULL) {
+ errno = EINVAL;
+ return (0);
+ }
+
+ return (ps->ps_ndx);
+}
+
+PE_Scn *
+pe_nextscn(PE *pe, PE_Scn *ps)
+{
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (ps == NULL)
+ ps = STAILQ_FIRST(&pe->pe_scn);
+ else
+ ps = STAILQ_NEXT(ps, ps_next);
+
+ while (ps != NULL) {
+ if (ps->ps_ndx >= 1 && ps->ps_ndx <= 0xFFFFU)
+ return (ps);
+ ps = STAILQ_NEXT(ps, ps_next);
+ }
+
+ return (NULL);
+}
+
+PE_Scn *
+pe_newscn(PE *pe)
+{
+ PE_Scn *ps, *tps, *_tps;
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (NULL);
+ }
+
+ if ((ps = libpe_alloc_scn(pe)) == NULL)
+ return (NULL);
+
+ if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) {
+ STAILQ_FOREACH_SAFE(tps, &pe->pe_scn, ps_next, _tps)
+ libpe_release_scn(tps);
+ pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER;
+ }
+
+ STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
+
+ ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION;
+ pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
+
+ return (ps);
+}
+
+PE_Scn *
+pe_insertscn(PE *pe, size_t ndx)
+{
+ PE_Scn *ps, *a, *b;
+
+ if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (NULL);
+ }
+
+ if ((ps = libpe_alloc_scn(pe)) == NULL)
+ return (NULL);
+
+ if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) {
+ STAILQ_FOREACH_SAFE(a, &pe->pe_scn, ps_next, b)
+ libpe_release_scn(a);
+ pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER;
+ }
+
+ b = NULL;
+ STAILQ_FOREACH(a, &pe->pe_scn, ps_next) {
+ if (a->ps_ndx & 0xFFFF0000U)
+ continue;
+ if (a->ps_ndx == ndx)
+ break;
+ b = a;
+ }
+
+ if (a == NULL) {
+ STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
+ if (b == NULL)
+ ps->ps_ndx = 1;
+ else
+ ps->ps_ndx = b->ps_ndx + 1;
+ } else if (b == NULL) {
+ STAILQ_INSERT_HEAD(&pe->pe_scn, ps, ps_next);
+ ps->ps_ndx = 1;
+ } else {
+ STAILQ_INSERT_AFTER(&pe->pe_scn, b, ps, ps_next);
+ ps->ps_ndx = ndx;
+ }
+
+ a = ps;
+ while ((a = STAILQ_NEXT(a, ps_next)) != NULL) {
+ if ((a->ps_ndx & 0xFFFF0000U) == 0)
+ a->ps_ndx++;
+ }
+
+ ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION;
+ pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
+
+ return (ps);
+}
+
+PE_SecHdr *
+pe_section_header(PE_Scn *ps)
+{
+
+ if (ps == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ return (&ps->ps_sh);
+}
+
+int
+pe_update_section_header(PE_Scn *ps, PE_SecHdr *sh)
+{
+ PE *pe;
+
+ if (ps == NULL || sh == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ pe = ps->ps_pe;
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ ps->ps_sh = *sh;
+ pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_symtab.c b/contrib/elftoolchain/libpe/pe_symtab.c
new file mode 100644
index 0000000..d0e90d1
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_symtab.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_symtab.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+int
+pe_update_symtab(PE *pe, char *symtab, size_t sz, unsigned int nsym)
+{
+ PE_Scn *ps;
+ PE_SecBuf *sb;
+ PE_SecHdr *sh;
+
+ if (pe == NULL || symtab == NULL || sz == 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ /* Remove the old symbol table. */
+ STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {
+ if (ps->ps_ndx == 0xFFFFFFFFU)
+ libpe_release_scn(ps);
+ }
+
+ /*
+ * Insert the new symbol table.
+ */
+
+ if ((ps = libpe_alloc_scn(pe)) == NULL)
+ return (-1);
+
+ STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
+ ps->ps_ndx = 0xFFFFFFFFU;
+ ps->ps_flags |= PE_F_DIRTY;
+
+ /*
+ * Set the symbol table section offset to the maximum to make sure
+ * that it will be placed in the end of the file during section
+ * layout.
+ */
+ sh = &ps->ps_sh;
+ sh->sh_rawptr = 0xFFFFFFFFU;
+ sh->sh_rawsize = sz;
+
+ /* Allocate the buffer. */
+ if ((sb = libpe_alloc_buffer(ps, 0)) == NULL)
+ return (-1);
+ sb->sb_flags |= PE_F_DIRTY;
+ sb->sb_pb.pb_size = sz;
+ sb->sb_pb.pb_buf = symtab;
+
+ pe->pe_nsym = nsym;
+
+ return (0);
+}
diff --git a/contrib/elftoolchain/libpe/pe_update.c b/contrib/elftoolchain/libpe/pe_update.c
new file mode 100644
index 0000000..ec2b2e5
--- /dev/null
+++ b/contrib/elftoolchain/libpe/pe_update.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2016 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "_libpe.h"
+
+ELFTC_VCSID("$Id: pe_update.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
+
+off_t
+pe_update(PE *pe)
+{
+ off_t off;
+
+ if (pe == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
+ errno = EACCES;
+ return (-1);
+ }
+
+ if (pe->pe_cmd == PE_C_RDWR || (pe->pe_cmd == PE_C_WRITE &&
+ (pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0)) {
+ if (lseek(pe->pe_fd, 0, SEEK_SET) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+ }
+
+ off = 0;
+
+ if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) {
+ if ((off = libpe_write_msdos_stub(pe, off)) < 0)
+ return (-1);
+
+ if ((off = libpe_write_pe_header(pe, off)) < 0)
+ return (-1);
+ }
+
+ if (libpe_resync_sections(pe, off) < 0)
+ return (-1);
+
+ if ((off = libpe_write_coff_header(pe, off)) < 0)
+ return (-1);
+
+ if ((off = libpe_write_section_headers(pe, off)) < 0)
+ return (-1);
+
+ if ((off = libpe_write_sections(pe, off)) < 0)
+ return (-1);
+
+ if (ftruncate(pe->pe_fd, off) < 0) {
+ errno = EIO;
+ return (-1);
+ }
+
+ return (off);
+}
diff --git a/contrib/elftoolchain/nm/os.NetBSD.mk b/contrib/elftoolchain/nm/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/nm/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/readelf/os.NetBSD.mk b/contrib/elftoolchain/readelf/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/readelf/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index a017023..d8e44dd 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -47,7 +47,16 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: readelf.c 3271 2015-12-11 18:53:08Z kaiwang27 $");
+ELFTC_VCSID("$Id: readelf.c 3395 2016-02-10 16:29:44Z emaste $");
+
+/* Backwards compatability for older FreeBSD releases. */
+#ifndef STB_GNU_UNIQUE
+#define STB_GNU_UNIQUE 10
+#endif
+#ifndef STT_SPARC_REGISTER
+#define STT_SPARC_REGISTER 13
+#endif
+
/*
* readelf(1) options.
@@ -338,7 +347,7 @@ static const char *phdr_type(unsigned int ptype);
static const char *ppc_abi_fp(uint64_t fp);
static const char *ppc_abi_vector(uint64_t vec);
static const char *r_type(unsigned int mach, unsigned int type);
-static void readelf_usage(void);
+static void readelf_usage(int status);
static void readelf_version(void);
static void search_loclist_at(struct readelf *re, Dwarf_Die die,
Dwarf_Unsigned lowpc);
@@ -348,7 +357,7 @@ static void set_cu_context(struct readelf *re, Dwarf_Half psize,
Dwarf_Half osize, Dwarf_Half ver);
static const char *st_bind(unsigned int sbind);
static const char *st_shndx(unsigned int shndx);
-static const char *st_type(unsigned int stype);
+static const char *st_type(unsigned int mach, unsigned int stype);
static const char *st_vis(unsigned int svis);
static const char *top_tag(unsigned int tag);
static void unload_sections(struct readelf *re);
@@ -958,6 +967,7 @@ st_bind(unsigned int sbind)
case STB_LOCAL: return "LOCAL";
case STB_GLOBAL: return "GLOBAL";
case STB_WEAK: return "WEAK";
+ case STB_GNU_UNIQUE: return "UNIQUE";
default:
if (sbind >= STB_LOOS && sbind <= STB_HIOS)
return "OS";
@@ -971,7 +981,7 @@ st_bind(unsigned int sbind)
}
static const char *
-st_type(unsigned int stype)
+st_type(unsigned int mach, unsigned int stype)
{
static char s_stype[32];
@@ -987,10 +997,12 @@ st_type(unsigned int stype)
if (stype >= STT_LOOS && stype <= STT_HIOS)
snprintf(s_stype, sizeof(s_stype), "OS+%#x",
stype - STT_LOOS);
- else if (stype >= STT_LOPROC && stype <= STT_HIPROC)
+ else if (stype >= STT_LOPROC && stype <= STT_HIPROC) {
+ if (mach == EM_SPARCV9 && stype == STT_SPARC_REGISTER)
+ return "REGISTER";
snprintf(s_stype, sizeof(s_stype), "PROC+%#x",
stype - STT_LOPROC);
- else
+ } else
snprintf(s_stype, sizeof(s_stype), "<unknown: %#x>",
stype);
return (s_stype);
@@ -1066,7 +1078,7 @@ r_type(unsigned int mach, unsigned int type)
case 4: return "R_386_PLT32";
case 5: return "R_386_COPY";
case 6: return "R_386_GLOB_DAT";
- case 7: return "R_386_JMP_SLOT";
+ case 7: return "R_386_JUMP_SLOT";
case 8: return "R_386_RELATIVE";
case 9: return "R_386_GOTOFF";
case 10: return "R_386_GOTPC";
@@ -1558,7 +1570,7 @@ r_type(unsigned int mach, unsigned int type)
case 4: return "R_X86_64_PLT32";
case 5: return "R_X86_64_COPY";
case 6: return "R_X86_64_GLOB_DAT";
- case 7: return "R_X86_64_JMP_SLOT";
+ case 7: return "R_X86_64_JUMP_SLOT";
case 8: return "R_X86_64_RELATIVE";
case 9: return "R_X86_64_GOTPCREL";
case 10: return "R_X86_64_32";
@@ -3465,9 +3477,10 @@ dump_symtab(struct readelf *re, int i)
continue;
}
printf("%6d:", j);
- printf(" %16.16jx", (uintmax_t)sym.st_value);
- printf(" %5ju", sym.st_size);
- printf(" %-7s", st_type(GELF_ST_TYPE(sym.st_info)));
+ printf(" %16.16jx", (uintmax_t) sym.st_value);
+ printf(" %5ju", (uintmax_t) sym.st_size);
+ printf(" %-7s", st_type(re->ehdr.e_machine,
+ GELF_ST_TYPE(sym.st_info)));
printf(" %-6s", st_bind(GELF_ST_BIND(sym.st_info)));
printf(" %-8s", st_vis(GELF_ST_VISIBILITY(sym.st_other)));
printf(" %3s", st_shndx(sym.st_shndx));
@@ -4303,7 +4316,7 @@ dump_compatibility_tag(uint8_t *p, uint8_t *pe)
uint64_t val;
val = _decode_uleb128(&p, pe);
- printf("flag = %ju, vendor = %s\n", val, p);
+ printf("flag = %ju, vendor = %s\n", (uintmax_t) val, p);
p += strlen((char *) p) + 1;
return (p);
@@ -4997,7 +5010,8 @@ dump_dwarf_line(struct readelf *re)
break;
case DW_LNS_set_isa:
isa = _decode_uleb128(&p, pe);
- printf(" Set isa to %ju\n", isa);
+ printf(" Set isa to %ju\n",
+ (uintmax_t) isa);
break;
default:
/* Unrecognized extended opcodes. */
@@ -5749,12 +5763,12 @@ dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base)
}
if (re->ec == ELFCLASS32)
printf("%08jx %08jx\n",
- ranges[j].dwr_addr1 + base0,
- ranges[j].dwr_addr2 + base0);
+ (uintmax_t) (ranges[j].dwr_addr1 + base0),
+ (uintmax_t) (ranges[j].dwr_addr2 + base0));
else
printf("%016jx %016jx\n",
- ranges[j].dwr_addr1 + base0,
- ranges[j].dwr_addr2 + base0);
+ (uintmax_t) (ranges[j].dwr_addr1 + base0),
+ (uintmax_t) (ranges[j].dwr_addr2 + base0));
}
}
@@ -6728,7 +6742,7 @@ dump_dwarf_loclist(struct readelf *re)
set_cu_context(re, la->la_cu_psize, la->la_cu_osize,
la->la_cu_ver);
for (i = 0; i < lcnt; i++) {
- printf(" %8.8jx ", la->la_off);
+ printf(" %8.8jx ", (uintmax_t) la->la_off);
if (llbuf[i]->ld_lopc == 0 && llbuf[i]->ld_hipc == 0) {
printf("<End of list>\n");
continue;
@@ -6850,13 +6864,15 @@ hex_dump(struct readelf *re)
if (find_dumpop(re, (size_t) i, s->name, HEX_DUMP, -1) == NULL)
continue;
(void) elf_errno();
- if ((d = elf_getdata(s->scn, NULL)) == NULL) {
+ if ((d = elf_getdata(s->scn, NULL)) == NULL &&
+ (d = elf_rawdata(s->scn, NULL)) == NULL) {
elferr = elf_errno();
if (elferr != 0)
warnx("elf_getdata failed: %s",
elf_errmsg(elferr));
continue;
}
+ (void) elf_errno();
if (d->d_size <= 0 || d->d_buf == NULL) {
printf("\nSection '%s' has no data to dump.\n",
s->name);
@@ -6905,13 +6921,15 @@ str_dump(struct readelf *re)
if (find_dumpop(re, (size_t) i, s->name, STR_DUMP, -1) == NULL)
continue;
(void) elf_errno();
- if ((d = elf_getdata(s->scn, NULL)) == NULL) {
+ if ((d = elf_getdata(s->scn, NULL)) == NULL &&
+ (d = elf_rawdata(s->scn, NULL)) == NULL) {
elferr = elf_errno();
if (elferr != 0)
warnx("elf_getdata failed: %s",
elf_errmsg(elferr));
continue;
}
+ (void) elf_errno();
if (d->d_size <= 0 || d->d_buf == NULL) {
printf("\nSection '%s' has no data to dump.\n",
s->name);
@@ -7370,10 +7388,13 @@ _read_lsb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read)
case 8:
ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
+ /* FALLTHROUGH */
case 4:
ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
+ /* FALLTHROUGH */
case 2:
ret |= ((uint64_t) src[1]) << 8;
+ /* FALLTHROUGH */
case 1:
ret |= src[0];
break;
@@ -7433,10 +7454,13 @@ _decode_lsb(uint8_t **data, int bytes_to_read)
case 8:
ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
+ /* FALLTHROUGH */
case 4:
ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
+ /* FALLTHROUGH */
case 2:
ret |= ((uint64_t) src[1]) << 8;
+ /* FALLTHROUGH */
case 1:
ret |= src[0];
break;
@@ -7558,6 +7582,10 @@ Usage: %s [options] file...\n\
-s | --syms | --symbols Print symbol tables.\n\
-t | --section-details Print additional information about sections.\n\
-v | --version Print a version identifier and exit.\n\
+ -w[afilmoprsFLR] | --debug-dump={abbrev,aranges,decodedline,frames,\n\
+ frames-interp,info,loc,macro,pubnames,\n\
+ ranges,Ranges,rawline,str}\n\
+ Display DWARF information.\n\
-x INDEX | --hex-dump=INDEX\n\
Display contents of a section as hexadecimal.\n\
-A | --arch-specific (accepted, but ignored)\n\
@@ -7574,10 +7602,10 @@ Usage: %s [options] file...\n\
static void
-readelf_usage(void)
+readelf_usage(int status)
{
fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME());
- exit(EXIT_FAILURE);
+ exit(status);
}
int
@@ -7596,7 +7624,7 @@ main(int argc, char **argv)
longopts, NULL)) != -1) {
switch(opt) {
case '?':
- readelf_usage();
+ readelf_usage(EXIT_SUCCESS);
break;
case 'A':
re->options |= RE_AA;
@@ -7621,7 +7649,7 @@ main(int argc, char **argv)
re->options |= RE_G;
break;
case 'H':
- readelf_usage();
+ readelf_usage(EXIT_SUCCESS);
break;
case 'h':
re->options |= RE_H;
@@ -7699,7 +7727,7 @@ main(int argc, char **argv)
argc -= optind;
if (argc == 0 || re->options == 0)
- readelf_usage();
+ readelf_usage(EXIT_FAILURE);
if (argc > 1)
re->flags |= DISPLAY_FILENAME;
diff --git a/contrib/elftoolchain/size/os.NetBSD.mk b/contrib/elftoolchain/size/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/size/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/strings/os.NetBSD.mk b/contrib/elftoolchain/strings/os.NetBSD.mk
new file mode 100644
index 0000000..ae214e3
--- /dev/null
+++ b/contrib/elftoolchain/strings/os.NetBSD.mk
@@ -0,0 +1,2 @@
+# TODO(#511): Revert after the source tree is -Wconversion clean.
+WARNS=5
diff --git a/contrib/elftoolchain/strings/strings.1 b/contrib/elftoolchain/strings/strings.1
index 15ad7a7..205afdf 100644
--- a/contrib/elftoolchain/strings/strings.1
+++ b/contrib/elftoolchain/strings/strings.1
@@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: strings.1 3195 2015-05-12 17:22:19Z emaste $
+.\" $Id: strings.1 3360 2016-01-24 18:34:06Z jkoshy $
.\"
-.Dd December 19, 2011
+.Dd January 24, 2016
.Dt STRINGS 1
.Os
.Sh NAME
@@ -100,6 +100,9 @@ Print a usage summary and exit.
Print the contiguous character sequence of at least
.Ar number
characters long, instead of the default of 4 characters.
+Argument
+.Ar number
+should specify a positive decimal integer.
.It Fl o
Equivalent to specifying
.Fl t Ar o .
diff --git a/contrib/elftoolchain/strings/strings.c b/contrib/elftoolchain/strings/strings.c
index 6eab165..f122eba 100644
--- a/contrib/elftoolchain/strings/strings.c
+++ b/contrib/elftoolchain/strings/strings.c
@@ -37,6 +37,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
#include <libelf.h>
@@ -45,7 +46,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: strings.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: strings.c 3360 2016-01-24 18:34:06Z jkoshy $");
enum return_code {
RETURN_OK,
@@ -73,10 +74,10 @@ enum encoding_style {
((c) == '\t' || isprint((c)) || \
(encoding == ENCODING_8BIT && (c) > 127)))
-
-static int encoding_size, entire_file, min_len, show_filename, show_loc;
+static int encoding_size, entire_file, show_filename, show_loc;
static enum encoding_style encoding;
static enum radix_style radix;
+static intmax_t min_len;
static struct option strings_longopts[] = {
{ "all", no_argument, NULL, 'a'},
@@ -144,7 +145,10 @@ main(int argc, char **argv)
show_filename = 1;
break;
case 'n':
- min_len = (int)strtoimax(optarg, (char**)NULL, 10);
+ min_len = strtoimax(optarg, (char**)NULL, 10);
+ if (min_len <= 0)
+ errx(EX_USAGE, "option -n should specify a "
+ "positive decimal integer.");
break;
case 'o':
show_loc = 1;
OpenPOWER on IntegriCloud