From: OneOfOne Date: Fri, 15 Jan 2016 17:24:44 +0000 (+0200) Subject: cmd/link: fix elf64phdr to allow using upx (and other broken ELF loaders). X-Git-Tag: go1.6rc1~92 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5e7110b92b959d22eba421953beaf1de8580f8f5;p=gostls13.git cmd/link: fix elf64phdr to allow using upx (and other broken ELF loaders). The linker already applies the fix for elf32, so this just extends it to elf64. Inspired by https://github.com/pwaller/goupx Fixes #13974 Change-Id: I65d92b5be9590657060a0e8e80ff5b86ba40017f Reviewed-on: https://go-review.googlesource.com/18690 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index a34cf3cac8..6d34978d5a 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -850,7 +850,26 @@ func Elfinit() { } } +// Make sure PT_LOAD is aligned properly and +// that there is no gap, +// correct ELF loaders will do this implicitly, +// but buggy ELF loaders like the one in some +// versions of QEMU and UPX won't. +func fixElfPhdr(e *ElfPhdr) { + frag := int(e.vaddr & (e.align - 1)) + + e.off -= uint64(frag) + e.vaddr -= uint64(frag) + e.paddr -= uint64(frag) + e.filesz += uint64(frag) + e.memsz += uint64(frag) +} + func elf64phdr(e *ElfPhdr) { + if e.type_ == PT_LOAD { + fixElfPhdr(e) + } + Thearch.Lput(e.type_) Thearch.Lput(e.flags) Thearch.Vput(e.off) @@ -863,16 +882,7 @@ func elf64phdr(e *ElfPhdr) { func elf32phdr(e *ElfPhdr) { if e.type_ == PT_LOAD { - // Correct ELF loaders will do this implicitly, - // but buggy ELF loaders like the one in some - // versions of QEMU won't. - frag := int(e.vaddr & (e.align - 1)) - - e.off -= uint64(frag) - e.vaddr -= uint64(frag) - e.paddr -= uint64(frag) - e.filesz += uint64(frag) - e.memsz += uint64(frag) + fixElfPhdr(e) } Thearch.Lput(e.type_)