FreeBSD Bugzilla – Attachment 166857 Details for
Bug 207091
[exp-run] installing ELF Tool Chain elfcopy in place of binutils objcopy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
update elftoolchain to r3395 (git rename detection disabled)
elftc-r3395.diff (text/plain), 213.34 KB, created by
Ed Maste
on 2016-02-10 22:28:46 UTC
(
hide
)
Description:
update elftoolchain to r3395 (git rename detection disabled)
Filename:
MIME Type:
Creator:
Ed Maste
Created:
2016-02-10 22:28:46 UTC
Size:
213.34 KB
patch
obsolete
>diff --git a/Makefile.inc1 b/Makefile.inc1 >index 173f70e..63d1b2f 100644 >--- a/Makefile.inc1 >+++ b/Makefile.inc1 >@@ -1638,6 +1638,7 @@ _binutils= gnu/usr.bin/binutils > .endif > .if ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no" > _elftctools= lib/libelftc \ >+ lib/libpe \ > usr.bin/elfcopy \ > usr.bin/nm \ > usr.bin/size \ >@@ -1650,6 +1651,7 @@ _elftctools+= usr.bin/addr2line > # If cross-building with an external binutils we still need to build strip for > # the target (for at least crunchide). > _elftctools= lib/libelftc \ >+ lib/libpe \ > usr.bin/elfcopy > .endif > >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..2054669 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 3381 2016-01-30 19:39:47Z jkoshy $"); > > enum options > { >@@ -722,6 +722,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 +1354,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 +1378,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 +1394,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\ >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..c003c13 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 3340 2016-01-17 15:00:56Z kaiwang27 $"); > > 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)); > } > > /* >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/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..f5ca7b31 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; >diff --git a/lib/Makefile b/lib/Makefile >index ccc6507..699aa6a 100644 >--- a/lib/Makefile >+++ b/lib/Makefile >@@ -80,6 +80,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ > libopie \ > libpam \ > libpcap \ >+ ${_libpe} \ > libpjdlog \ > ${_libpmc} \ > ${_libproc} \ >@@ -184,6 +185,7 @@ _cuse= libcuse > > .if ${MK_TOOLCHAIN} != "no" > _libelftc= libelftc >+_libpe= libpe > .endif > > .if ${MK_FILE} != "no" >diff --git a/lib/libelftc/elftc_version.c b/lib/libelftc/elftc_version.c >index 0a1dd12..3054999 100644 >--- a/lib/libelftc/elftc_version.c >+++ b/lib/libelftc/elftc_version.c >@@ -6,5 +6,5 @@ > const char * > elftc_version(void) > { >- return "elftoolchain r3272M"; >+ return "elftoolchain r3395M"; > } >diff --git a/lib/libpe/Makefile b/lib/libpe/Makefile >new file mode 100644 >index 0000000..877b331 >--- /dev/null >+++ b/lib/libpe/Makefile >@@ -0,0 +1,34 @@ >+# $FreeBSD$ >+.include <bsd.own.mk> >+ >+INTERNALLIB= >+ >+ELFTCDIR= ${.CURDIR}/../../contrib/elftoolchain >+ >+.PATH: ${ELFTCDIR}/libpe >+ >+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 >+ >+CFLAGS+=-I${ELFTCDIR}/libpe -I${ELFTCDIR}/common >+ >+MAN= >+ >+.include <bsd.lib.mk> >diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk >index 28c2368..d27597f 100644 >--- a/share/mk/src.libnames.mk >+++ b/share/mk/src.libnames.mk >@@ -39,6 +39,7 @@ _INTERNALLIBS= \ > openbsd \ > opts \ > parse \ >+ pe \ > readline \ > sl \ > sm \ >@@ -367,6 +368,9 @@ LDADD+= ${LDADD_${_l}} > LIBELFTCDIR= ${OBJTOP}/lib/libelftc > LIBELFTC?= ${LIBELFTCDIR}/libelftc.a > >+LIBPEDIR= ${OBJTOP}/lib/libpe >+LIBPE?= ${LIBPEDIR}/libpe.a >+ > LIBREADLINEDIR= ${OBJTOP}/gnu/lib/libreadline/readline > LIBREADLINE?= ${LIBREADLINEDIR}/libreadline.a > >diff --git a/usr.bin/elfcopy/Makefile b/usr.bin/elfcopy/Makefile >index dc6dd47..b674595 100644 >--- a/usr.bin/elfcopy/Makefile >+++ b/usr.bin/elfcopy/Makefile >@@ -17,13 +17,14 @@ CLEANFILES+= objcopy.1 > PROG= elfcopy > .endif > >-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 pe.c > > WARNS?= 5 > >-LIBADD= archive elftc elf >+LIBADD= archive elftc elf pe > >-CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common >+CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/libpe -I${ELFTCDIR}/common >+CFLAGS+=-DWITH_PE=1 > > MAN= ${PROG}.1 strip.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 207091
:
166851
|
166852
|
166856
|
166857
|
166986