Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <>2013-06-05 11:57:40 +0400
committercvs2svn <>2013-06-05 11:57:40 +0400
commit310a2eeef1d094d59ea9897be0ddb1b33869b885 (patch)
tree6c061f692be2a0be45d81351d4b9dfc06ec9fe9c /winsup/cygwin/autoload.cc
parentc82eac05c783fa1cb82eac9216dab1ed8aa482ae (diff)
This commit was manufactured by cvs2svn to create tag 'cygwin-cygwin-1_7_19-release
1_7_19-release'. Sprout from cygwin-64bit-premerge-branch 2013-04-22 17:11:23 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-' Cherrypick from master 2013-06-05 07:57:39 UTC Corinna Vinschen <corinna@vinschen.de> ' * faq-programming.xml: Convert url to refer to new flat faq.html file.': COPYING.NEWLIB ChangeLog config.guess config.sub config/ChangeLog config/bootstrap-asan.mk config/dfp.m4 config/picflag.m4 include/ChangeLog include/elf/ChangeLog include/elf/aarch64.h include/elf/common.h include/elf/mips.h include/elf/msp430.h include/opcode/ChangeLog include/opcode/avr.h include/opcode/mips.h include/opcode/msp430.h newlib/ChangeLog newlib/MAINTAINERS newlib/configure newlib/configure.host newlib/configure.in newlib/libc/configure newlib/libc/configure.in newlib/libc/ctype/ctype_.c newlib/libc/ctype/isalnum.c newlib/libc/ctype/isalpha.c newlib/libc/ctype/isblank.c newlib/libc/ctype/iscntrl.c newlib/libc/ctype/isdigit.c newlib/libc/ctype/islower.c newlib/libc/ctype/isprint.c newlib/libc/ctype/ispunct.c newlib/libc/ctype/isxdigit.c newlib/libc/include/machine/ieeefp.h newlib/libc/include/machine/setjmp.h newlib/libc/include/reent.h newlib/libc/include/sys/cdefs.h newlib/libc/include/sys/config.h newlib/libc/include/sys/features.h newlib/libc/include/sys/reent.h newlib/libc/include/sys/stat.h newlib/libc/libc.texinfo newlib/libc/machine/arm/Makefile.am newlib/libc/machine/arm/Makefile.in newlib/libc/machine/arm/memcpy-armv7a.S newlib/libc/machine/arm/memcpy-armv7m.S newlib/libc/machine/arm/memcpy-stub.c newlib/libc/machine/arm/memcpy.S newlib/libc/machine/arm/strcmp.S newlib/libc/machine/configure newlib/libc/machine/configure.in newlib/libc/machine/powerpc/Makefile.am newlib/libc/machine/powerpc/Makefile.in newlib/libc/reent/reent.c newlib/libc/stdio/fgetc.c newlib/libc/stdio/fgetwc.c newlib/libc/stdio/fgetws.c newlib/libc/stdio/findfp.c newlib/libc/stdio/fputc.c newlib/libc/stdio/fputwc.c newlib/libc/stdio/fputws.c newlib/libc/stdio/getc.c newlib/libc/stdio/getchar.c newlib/libc/stdio/local.h newlib/libc/stdio/putc.c newlib/libc/stdio/putchar.c newlib/libc/stdio/scanf.c newlib/libc/stdio/setvbuf.c newlib/libc/stdio/ungetwc.c newlib/libc/stdio/vfscanf.c newlib/libc/stdio/vfwscanf.c newlib/libc/stdio/viprintf.c newlib/libc/stdio/viscanf.c newlib/libc/stdio/vprintf.c newlib/libc/stdio/vscanf.c newlib/libc/stdio/vwprintf.c newlib/libc/stdio/vwscanf.c newlib/libc/stdio/wscanf.c newlib/libc/stdlib/Makefile.am newlib/libc/stdlib/Makefile.in newlib/libc/stdlib/__atexit.c newlib/libc/stdlib/__call_atexit.c newlib/libc/stdlib/ecvtbuf.c newlib/libc/stdlib/mblen.c newlib/libc/stdlib/mbrlen.c newlib/libc/stdlib/mbrtowc.c newlib/libc/stdlib/mbtowc.c newlib/libc/stdlib/nano-mallocr.c newlib/libc/stdlib/rand.c newlib/libc/stdlib/strtod.c newlib/libc/stdlib/wcrtomb.c newlib/libc/stdlib/wctob.c newlib/libc/stdlib/wctomb.c newlib/libc/string/strtok.c newlib/libc/time/asctime.c newlib/libc/time/gmtime.c newlib/libc/time/lcltime.c newlib/libm/libm.texinfo winsup/cygserver/ChangeLog winsup/cygserver/ChangeLog.64bit winsup/cygserver/Makefile.in winsup/cygserver/bsd_helper.cc winsup/cygserver/bsd_helper.h winsup/cygserver/bsd_log.cc winsup/cygserver/bsd_log.h winsup/cygserver/bsd_mutex.cc winsup/cygserver/client.cc winsup/cygserver/cygserver.cc winsup/cygserver/msg.cc winsup/cygserver/process.h winsup/cygserver/sem.cc winsup/cygserver/shm.cc winsup/cygserver/sysv_shm.cc winsup/cygserver/threaded_queue.h winsup/cygwin/ChangeLog winsup/cygwin/ChangeLog.64bit winsup/cygwin/Makefile.in winsup/cygwin/aclocal.m4 winsup/cygwin/advapi32.cc winsup/cygwin/autoload.cc winsup/cygwin/automode.c winsup/cygwin/binmode.c winsup/cygwin/child_info.h winsup/cygwin/common.din winsup/cygwin/configure winsup/cygwin/configure.ac winsup/cygwin/cpuid.h winsup/cygwin/cygerrno.h winsup/cygwin/cygheap.cc winsup/cygwin/cygheap.h winsup/cygwin/cygmagic winsup/cygwin/cygmalloc.h winsup/cygwin/cygserver.h winsup/cygwin/cygserver_ipc.h winsup/cygwin/cygthread.cc winsup/cygwin/cygtls.cc winsup/cygwin/cygtls.h winsup/cygwin/cygwin.sc.in winsup/cygwin/dcrt0.cc winsup/cygwin/debug.h winsup/cygwin/devices.cc winsup/cygwin/devices.h winsup/cygwin/devices.in winsup/cygwin/dir.cc winsup/cygwin/dlfcn.cc winsup/cygwin/dll_init.cc winsup/cygwin/dll_init.h winsup/cygwin/dtable.cc winsup/cygwin/environ.cc winsup/cygwin/environ.h winsup/cygwin/errno.cc winsup/cygwin/exception.h winsup/cygwin/exceptions.cc winsup/cygwin/external.cc winsup/cygwin/fcntl.cc winsup/cygwin/fenv.cc winsup/cygwin/fhandler.cc winsup/cygwin/fhandler.h winsup/cygwin/fhandler_clipboard.cc winsup/cygwin/fhandler_console.cc winsup/cygwin/fhandler_dev.cc winsup/cygwin/fhandler_disk_file.cc winsup/cygwin/fhandler_dsp.cc winsup/cygwin/fhandler_fifo.cc winsup/cygwin/fhandler_floppy.cc winsup/cygwin/fhandler_mailslot.cc winsup/cygwin/fhandler_mem.cc winsup/cygwin/fhandler_netdrive.cc winsup/cygwin/fhandler_proc.cc winsup/cygwin/fhandler_process.cc winsup/cygwin/fhandler_procnet.cc winsup/cygwin/fhandler_procsys.cc winsup/cygwin/fhandler_procsysvipc.cc winsup/cygwin/fhandler_random.cc winsup/cygwin/fhandler_raw.cc winsup/cygwin/fhandler_registry.cc winsup/cygwin/fhandler_serial.cc winsup/cygwin/fhandler_socket.cc winsup/cygwin/fhandler_tape.cc winsup/cygwin/fhandler_termios.cc winsup/cygwin/fhandler_tty.cc winsup/cygwin/fhandler_virtual.cc winsup/cygwin/fhandler_virtual.h winsup/cygwin/fhandler_windows.cc winsup/cygwin/fhandler_zero.cc winsup/cygwin/flock.cc winsup/cygwin/fork.cc winsup/cygwin/gendef winsup/cygwin/gentls_offsets winsup/cygwin/glob.cc winsup/cygwin/globals.cc winsup/cygwin/grp.cc winsup/cygwin/heap.cc winsup/cygwin/hookapi.cc winsup/cygwin/i686.din winsup/cygwin/include/a.out.h winsup/cygwin/include/asm/byteorder.h winsup/cygwin/include/bits/wordsize.h winsup/cygwin/include/cygwin/acl.h winsup/cygwin/include/cygwin/config.h winsup/cygwin/include/cygwin/cygwin_dll.h winsup/cygwin/include/cygwin/grp.h winsup/cygwin/include/cygwin/if.h winsup/cygwin/include/cygwin/ipc.h winsup/cygwin/include/cygwin/msg.h winsup/cygwin/include/cygwin/sem.h winsup/cygwin/include/cygwin/shm.h winsup/cygwin/include/cygwin/signal.h winsup/cygwin/include/cygwin/socket.h winsup/cygwin/include/cygwin/stat.h winsup/cygwin/include/cygwin/stdlib.h winsup/cygwin/include/cygwin/sysproto.h winsup/cygwin/include/cygwin/time.h winsup/cygwin/include/cygwin/types.h winsup/cygwin/include/cygwin/version.h winsup/cygwin/include/fcntl.h winsup/cygwin/include/fts.h winsup/cygwin/include/ftw.h winsup/cygwin/include/glob.h winsup/cygwin/include/inttypes.h winsup/cygwin/include/io.h winsup/cygwin/include/limits.h winsup/cygwin/include/mntent.h winsup/cygwin/include/stdint.h winsup/cygwin/include/sys/cygwin.h winsup/cygwin/include/sys/dirent.h winsup/cygwin/include/sys/resource.h winsup/cygwin/include/sys/socket.h winsup/cygwin/include/sys/strace.h winsup/cygwin/init.cc winsup/cygwin/ioctl.cc winsup/cygwin/ipc.cc winsup/cygwin/kernel32.cc winsup/cygwin/lc_msg.h winsup/cygwin/lib/_cygwin_crt0_common.cc winsup/cygwin/lib/crt0.h winsup/cygwin/lib/cygwin_attach_dll.c winsup/cygwin/lib/premain0.c winsup/cygwin/lib/premain1.c winsup/cygwin/lib/premain2.c winsup/cygwin/lib/premain3.c winsup/cygwin/libc/arc4random.cc winsup/cygwin/libc/base64.c winsup/cygwin/libc/bsdlib.cc winsup/cygwin/libc/fts.c winsup/cygwin/libc/ftw.c winsup/cygwin/libc/inet_network.c winsup/cygwin/libc/minires-os-if.c winsup/cygwin/libc/minires.c winsup/cygwin/libc/nftw.c winsup/cygwin/libc/rcmd.cc winsup/cygwin/libc/rexec.cc winsup/cygwin/libstdcxx_wrapper.cc winsup/cygwin/localtime.cc winsup/cygwin/malloc_wrapper.cc winsup/cygwin/miscfuncs.cc winsup/cygwin/mkimport winsup/cygwin/mktemp.cc winsup/cygwin/mmap.cc winsup/cygwin/mount.cc winsup/cygwin/mount.h winsup/cygwin/msg.cc winsup/cygwin/mtinfo.h winsup/cygwin/net.cc winsup/cygwin/netdb.cc winsup/cygwin/nfs.h winsup/cygwin/nlsfuncs.cc winsup/cygwin/ntdll.h winsup/cygwin/ntea.cc winsup/cygwin/passwd.cc winsup/cygwin/path.cc winsup/cygwin/path.h winsup/cygwin/perprocess.h winsup/cygwin/pinfo.cc winsup/cygwin/pinfo.h winsup/cygwin/pipe.cc winsup/cygwin/poll.cc winsup/cygwin/posix.sgml winsup/cygwin/posix_ipc.cc winsup/cygwin/profil.c winsup/cygwin/profil.h winsup/cygwin/pseudo-reloc.cc winsup/cygwin/pwdgrp.h winsup/cygwin/regex/engine.c winsup/cygwin/regex/regcomp.c winsup/cygwin/registry.cc winsup/cygwin/regparm.h winsup/cygwin/release/1.7.19 winsup/cygwin/resource.cc winsup/cygwin/sched.cc winsup/cygwin/sec_acl.cc winsup/cygwin/sec_auth.cc winsup/cygwin/sec_helper.cc winsup/cygwin/security.cc winsup/cygwin/security.h winsup/cygwin/select.cc winsup/cygwin/select.h winsup/cygwin/sem.cc winsup/cygwin/shared.cc winsup/cygwin/shared_info.h winsup/cygwin/shm.cc winsup/cygwin/signal.cc winsup/cygwin/sigproc.cc winsup/cygwin/sigproc.h winsup/cygwin/smallprint.cc winsup/cygwin/spawn.cc winsup/cygwin/speclib winsup/cygwin/spinlock.h winsup/cygwin/strace.cc winsup/cygwin/strfuncs.cc winsup/cygwin/strsig.cc winsup/cygwin/sync.cc winsup/cygwin/sync.h winsup/cygwin/syscalls.cc winsup/cygwin/sysconf.cc winsup/cygwin/syslog.cc winsup/cygwin/termios.cc winsup/cygwin/textmode.c winsup/cygwin/textreadmode.c winsup/cygwin/thread.cc winsup/cygwin/thread.h winsup/cygwin/timer.cc winsup/cygwin/times.cc winsup/cygwin/tlsoffsets.h winsup/cygwin/tlsoffsets64.h winsup/cygwin/tty.cc winsup/cygwin/tty.h winsup/cygwin/uinfo.cc winsup/cygwin/wait.cc winsup/cygwin/winbase.h winsup/cygwin/wincap.cc winsup/cygwin/wincap.h winsup/cygwin/window.cc winsup/cygwin/winlean.h winsup/cygwin/winsup.h winsup/cygwin/wow64.cc winsup/cygwin/wow64.h winsup/cygwin/x86_64.din winsup/doc/.cvsignore winsup/doc/ChangeLog winsup/doc/Makefile.in winsup/doc/Wishlist winsup/doc/bodysnatcher.pl winsup/doc/configure winsup/doc/configure.ac winsup/doc/cygserver.xml winsup/doc/cygwin-api.in.xml winsup/doc/cygwin-ug-net.xml winsup/doc/cygwin.xsl winsup/doc/cygwinenv.xml winsup/doc/dll.xml winsup/doc/effectively.xml winsup/doc/faq-api.xml winsup/doc/faq-copyright.xml winsup/doc/faq-programming.xml winsup/doc/faq-resources.xml winsup/doc/faq-setup.xml winsup/doc/faq-using.xml winsup/doc/faq-what.xml winsup/doc/faq.xml winsup/doc/filemodes.xml winsup/doc/gcc.xml winsup/doc/gdb.xml winsup/doc/highlights.xml winsup/doc/legal.xml winsup/doc/new-features.xml winsup/doc/ntsec.xml winsup/doc/ov-ex-unix.xml winsup/doc/ov-ex-win.xml winsup/doc/overview.xml winsup/doc/pathnames.xml winsup/doc/programming.xml winsup/doc/setup-env.xml winsup/doc/setup-files.xml winsup/doc/setup-locale.xml winsup/doc/setup-maxmem.xml winsup/doc/setup-net.xml winsup/doc/specialnames.xml winsup/doc/textbinary.xml winsup/doc/ug-info.xml winsup/doc/using.xml winsup/doc/windres.xml winsup/doc/xidepend winsup/lsaauth/ChangeLog winsup/lsaauth/ChangeLog.64bit winsup/lsaauth/Makefile.in winsup/lsaauth/configure winsup/lsaauth/configure.ac winsup/utils/ChangeLog winsup/utils/ChangeLog.64bit winsup/utils/Makefile.in winsup/utils/aclocal.m4 winsup/utils/configure winsup/utils/cygcheck.cc winsup/utils/dumper.cc winsup/utils/dumper.h winsup/utils/kill.cc winsup/utils/ldd.cc winsup/utils/locale.cc winsup/utils/mkgroup.c winsup/utils/mkpasswd.c winsup/utils/module_info.cc winsup/utils/mount.cc winsup/utils/parse_pe.cc winsup/utils/passwd.c winsup/utils/path.cc winsup/utils/ps.cc winsup/utils/regtool.cc winsup/utils/ssp.c winsup/utils/strace.cc winsup/utils/tzset.c winsup/utils/utils.xml Delete: COPYING3 COPYING3.LIB config.rpath configure.ac ltgcc.m4 newlib/libc/machine/aarch64/Makefile.am newlib/libc/machine/aarch64/Makefile.in newlib/libc/machine/aarch64/aclocal.m4 newlib/libc/machine/aarch64/configure newlib/libc/machine/aarch64/configure.in newlib/libc/machine/aarch64/memcmp-stub.c newlib/libc/machine/aarch64/memcmp.S newlib/libc/machine/aarch64/memcpy-stub.c newlib/libc/machine/aarch64/memcpy.S newlib/libc/machine/aarch64/memmove-stub.c newlib/libc/machine/aarch64/memmove.S newlib/libc/machine/aarch64/memset-stub.c newlib/libc/machine/aarch64/memset.S newlib/libc/machine/aarch64/setjmp.S newlib/libc/machine/aarch64/strcmp-stub.c newlib/libc/machine/aarch64/strcmp.S newlib/libc/machine/aarch64/strlen-stub.c newlib/libc/machine/aarch64/strlen.S newlib/libc/machine/aarch64/strncmp-stub.c newlib/libc/machine/aarch64/strncmp.S newlib/libc/machine/aarch64/strnlen-stub.c newlib/libc/machine/aarch64/strnlen.S newlib/libc/machine/epiphany/Makefile.am newlib/libc/machine/epiphany/Makefile.in newlib/libc/machine/epiphany/aclocal.m4 newlib/libc/machine/epiphany/configure newlib/libc/machine/epiphany/configure.in newlib/libc/machine/epiphany/machine/stdlib.h newlib/libc/machine/epiphany/setjmp.S newlib/libc/machine/powerpc/times.c newlib/libc/sys/epiphany/Makefile.am newlib/libc/sys/epiphany/Makefile.in newlib/libc/sys/epiphany/aclocal.m4 newlib/libc/sys/epiphany/configure newlib/libc/sys/epiphany/configure.in newlib/libc/sys/epiphany/e_printf.c newlib/libm/machine/aarch64/Makefile.am newlib/libm/machine/aarch64/Makefile.in newlib/libm/machine/aarch64/aclocal.m4 newlib/libm/machine/aarch64/configure newlib/libm/machine/aarch64/configure.in newlib/libm/machine/aarch64/s_ceil.c newlib/libm/machine/aarch64/s_floor.c newlib/libm/machine/aarch64/s_fma.c newlib/libm/machine/aarch64/s_fmax.c newlib/libm/machine/aarch64/s_fmin.c newlib/libm/machine/aarch64/s_llrint.c newlib/libm/machine/aarch64/s_llround.c newlib/libm/machine/aarch64/s_lrint.c newlib/libm/machine/aarch64/s_lround.c newlib/libm/machine/aarch64/s_nearbyint.c newlib/libm/machine/aarch64/s_rint.c newlib/libm/machine/aarch64/s_round.c newlib/libm/machine/aarch64/s_trunc.c newlib/libm/machine/aarch64/sf_ceil.c newlib/libm/machine/aarch64/sf_floor.c newlib/libm/machine/aarch64/sf_fma.c newlib/libm/machine/aarch64/sf_fmax.c newlib/libm/machine/aarch64/sf_fmin.c newlib/libm/machine/aarch64/sf_llrint.c newlib/libm/machine/aarch64/sf_llround.c newlib/libm/machine/aarch64/sf_lrint.c newlib/libm/machine/aarch64/sf_lround.c newlib/libm/machine/aarch64/sf_nearbyint.c newlib/libm/machine/aarch64/sf_rint.c newlib/libm/machine/aarch64/sf_round.c newlib/libm/machine/aarch64/sf_trunc.c winsup/cygwin/cygwin.din winsup/cygwin/cygwin.sc winsup/doc/cygserver.sgml winsup/doc/cygwin-api.in.sgml winsup/doc/cygwin-ug-net.in.sgml winsup/doc/cygwin-ug.in.sgml winsup/doc/cygwin.dsl winsup/doc/cygwinenv.sgml winsup/doc/dll.sgml winsup/doc/effectively.sgml winsup/doc/faq-sections.xml winsup/doc/filemodes.sgml winsup/doc/gcc.sgml winsup/doc/gdb.sgml winsup/doc/legal.sgml winsup/doc/new-features.sgml winsup/doc/ntsec.sgml winsup/doc/overview.sgml winsup/doc/overview2.sgml winsup/doc/pathnames.sgml winsup/doc/programming.sgml winsup/doc/setup-net.sgml winsup/doc/setup.sgml winsup/doc/setup2.sgml winsup/doc/textbinary.sgml winsup/doc/using.sgml winsup/doc/windres.sgml winsup/utils/utils.sgml
Diffstat (limited to 'winsup/cygwin/autoload.cc')
-rw-r--r--winsup/cygwin/autoload.cc245
1 files changed, 213 insertions, 32 deletions
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 3e61f837f..75771a2b6 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -32,34 +32,60 @@ bool NO_COPY wsock_started;
*
* So, immediately following the the call to one of the above routines
* we have:
- * DLL info (4 bytes) Pointer to a block of information concerning
+ * DLL info (4/8 bytes) Pointer to a block of information concerning
* the DLL (see below).
* DLL args (4 bytes) The number of arguments pushed on the stack by
* the call. If this is an odd value then this
* is a flag that non-existence of this function
* is not a fatal error
+ * func addr (8 bytes) (64 bit ONLY!)
+ * Address of the actual Win32 function. For the
+ * reason why this is necessary, see the below
+ * description of the load_state.
* func name (n bytes) asciz string containing the name of the function
* to be loaded.
*
* The DLL info block consists of the following
- * load_state (4 bytes) Pointer to a word containing the routine used
+ * load_state (4/8 bytes) Pointer to a word containing the routine used
* to eventually invoke the function. Initially
- * points to an init function which loads the
- * DLL, gets the process's load address,
- * changes the contents here to point to the
- * function address, and changes the call *(%eax)
- * to a jmp func. If the initialization has been
- * done, only the load part is done.
- * DLL handle (4 bytes) The handle to use when loading the DLL.
+ * points to an init function which loads the DLL,
+ * gets the process's load address, changes the contents
+ * here to point to the function address, and changes
+ * the address argument of the initial jmp call.
+ * On 64 bit, the jmp is not tweaked directly. Rather,
+ * the address of the Win32 function is stored in the
+ * aforementioned Win32 function address slot and fetched
+ * there for a jmp *%rax call. This indirection is
+ * necessary to workaround the lack of a jmp opcode with
+ * offset values > 32 bit. If the initialization has
+ * been done, only the load part is done.
+ * DLL handle (4/8 bytes) The handle to use when loading the DLL.
* DLL locker (4 bytes) Word to use to avoid multi-thread access during
* initialization.
- * extra init (4 bytes) Extra initialization function.
+ * extra init (4/8 bytes) Extra initialization function.
* DLL name (n bytes) asciz string containing the name of the DLL.
*/
/* LoadDLLprime is used to prime the DLL info information, providing an
additional initialization routine to call prior to calling the first
function. */
+#ifdef __x86_64__
+#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
+.ifndef " #dllname "_primed \n\
+ .section .data_cygwin_nocopy,\"w\" \n\
+ .align 8 \n\
+."#dllname "_info: \n\
+ .quad _std_dll_init \n\
+ .quad " #no_resolve_on_fork " \n\
+ .long -1 \n\
+ .align 8 \n\
+ .quad " #init_also " \n\
+ .string16 \"" #dllname ".dll\" \n\
+ .text \n\
+ .set " #dllname "_primed, 1 \n\
+.endif \n\
+");
+#else
#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
.ifndef " #dllname "_primed \n\
.section .data_cygwin_nocopy,\"w\" \n\
@@ -74,6 +100,7 @@ bool NO_COPY wsock_started;
.set " #dllname "_primed, 1 \n\
.endif \n\
");
+#endif
/* Create a "decorated" name */
#define mangle(name, n) #name "@" #n
@@ -88,6 +115,32 @@ bool NO_COPY wsock_started;
LoadDLLfuncEx3(name, n, dllname, notimp, err, 0)
/* Main DLL setup stuff. */
+#ifdef __x86_64__
+#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
+ LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
+ __asm__ (" \n\
+ .section ." #dllname "_autoload_text,\"wx\" \n\
+ .global " #name " \n\
+ .global _win32_" #name " \n\
+ .align 16 \n\
+" #name ": \n\
+_win32_" #name ": \n\
+ movq 3f(%rip),%rax \n\
+ jmp *%rax \n\
+1:movq 2f(%rip),%rax \n\
+ push %rbp # Keep 16 byte aligned \n\
+ push %r9 \n\
+ push %r8 \n\
+ push %rdx \n\
+ push %rcx \n\
+ call *(%rax) \n\
+2:.quad ." #dllname "_info \n\
+ .long (" #n "+" #notimp ") | (((" #err ") & 0xff) <<16) \n\
+3:.quad 1b \n\
+ .asciz \"" #name "\" \n\
+ .text \n\
+");
+#else
#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
__asm__ (" \n\
@@ -106,6 +159,7 @@ _win32_" mangle (name, n) ": \n\
.asciz \"" #name "\" \n\
.text \n\
");
+#endif
/* DLL loader helper functions used during initialization. */
@@ -121,6 +175,69 @@ extern "C" void dll_chain () __asm__ ("dll_chain");
extern "C" {
+#ifdef __x86_64__
+__asm__ (" \n\
+ .section .rdata,\"r\" \n\
+msg1: \n\
+ .ascii \"couldn't dynamically determine load address for '%s' (handle %p), %E\\0\"\n\
+ \n\
+ .text \n\
+ .p2align 4,,15 \n\
+noload: \n\
+ movq 40(%rsp),%rdx # Get the address of the information block\n\
+ movl 8(%rdx),%eax # Should we 'ignore' the lack \n\
+ test $1,%eax # of this function? \n\
+ jz 1f # Nope. \n\
+ andl $0xffff0000,%eax# upper word (== desired return value) \n\
+ movl %eax,32(%rsp) # Save for later (in shadow space) \n\
+ movl $127,%ecx # ERROR_PROC_NOT_FOUND \n\
+ call SetLastError # Set it \n\
+ movl 32(%rsp),%eax # Get back return value \n\
+ sarl $16,%eax # swap to low order word \n\
+ addq $40,%rsp # Revert stack \n\
+ pop %r10 # Drop pointer to 'return address' \n\
+ pop %rcx # Restore arg registers \n\
+ pop %rdx \n\
+ pop %r8 \n\
+ pop %r9 \n\
+ pop %rbp # ...and restore frame pointer \n\
+ ret # Return \n\
+1: \n\
+ movq (%rdx),%rax # Handle value \n\
+ movq 8(%rax),%r8 \n\
+ lea 20(%rdx),%rdx # Location of name of function \n\
+ lea msg1(%rip),%rcx # The message \n\
+ call api_fatal # Print message. Never returns \n\
+ \n\
+ .globl dll_func_load \n\
+dll_func_load: \n\
+ movq (%rsp),%rdx # 'Return address' contains load info \n\
+ movq (%rdx),%rcx # Where handle lives \n\
+ movq 8(%rcx),%rcx # Address of Handle to DLL \n\
+ addq $20,%rdx # Address of name of function to load \n\
+ subq $40,%rsp # Shadow space + 8 byte for alignment \n\
+ call GetProcAddress # Load it \n\
+ test %rax,%rax # Success? \n\
+ jne gotit # Yes \n\
+ jmp noload # Issue an error or return \n\
+gotit: \n\
+ addq $40,%rsp # Revert stack \n\
+ pop %r10 # Pointer to 'return address' \n\
+ movq %rax,12(%r10) # Move absolute address to address slot \n\
+ subq $25,%r10 # Point to jmp \n\
+ pop %rcx # Restore arg registers \n\
+ pop %rdx \n\
+ pop %r8 \n\
+ pop %r9 \n\
+ pop %rbp # ...and restore frame pointer \n\
+ jmp *%r10 # Jump to actual function \n\
+ \n\
+ .global dll_chain \n\
+dll_chain: \n\
+ push %rax # Restore 'return address' \n\
+ jmp *%rdx # Jump to next init function \n\
+");
+#else
__asm__ (" \n\
.text \n\
msg1: \n\
@@ -177,13 +294,14 @@ dll_chain: \n\
pushl %eax # Restore 'return address' \n\
jmp *%edx # Jump to next init function \n\
");
+#endif
/* C representations of the two info blocks described above.
FIXME: These structures confuse gdb for some reason. GDB can print
the whole structure but has problems with the name field? */
struct dll_info
{
- DWORD load_state;
+ UINT_PTR load_state;
HANDLE handle;
LONG here;
void (*init) ();
@@ -194,14 +312,22 @@ struct func_info
{
struct dll_info *dll;
LONG decoration;
+#ifdef __x86_64__
+ UINT_PTR func_addr;
+#endif
char name[];
};
/* Mechanism for setting up info for passing to dll_chain routines. */
+#ifdef __x86_64__
+typedef __uint128_t two_addr_t;
+#else
+typedef __uint64_t two_addr_t;
+#endif
union retchain
{
- struct {long high; long low;};
- long long ll;
+ struct {uintptr_t high; uintptr_t low;};
+ two_addr_t ll;
};
@@ -228,10 +354,56 @@ dll_load (HANDLE& handle, WCHAR *name)
#define RETRY_COUNT 10
/* The standard DLL initialization routine. */
-__attribute__ ((used, noinline)) static long long
+#ifdef __x86_64__
+
+/* On x86_64, we need assembler wrappers for std_dll_init and wsock_init.
+ In the x86_64 ABI it's no safe bet that frame[1] (aka 8(%rbp)) contains
+ the return address. Consequentially, if we try to overwrite frame[1]
+ with the address of dll_chain, we end up with a scrambled stack, the
+ result depending on the optimization settings and the current frame of
+ mind of the compiler. So for x86_64, we disable overwriting the return
+ address in the real std_dll_init/wsock_init function, but rather do this
+ in the wrapper, after return from the function, when we exactly know
+ where the original return address is stored on the stack. */
+
+#define INIT_WRAPPER(func) \
+__asm__ (" \n\
+ .text \n\
+ .p2align 4,,15 \n\
+ .seh_proc _" #func " \n\
+_" #func ": \n\
+ pushq %rbp \n\
+ .seh_pushreg %rbp \n\
+ movq %rsp,%rbp \n\
+ .seh_setframe %rbp,0 \n\
+ subq $0x20,%rsp \n\
+ .seh_stackalloc 32 \n\
+ .seh_endprologue \n\
+ movq 0x28(%rsp),%rcx # return address as parameter \n\
+ call " #func " \n\
+ movdqa %xmm0,0x10(%rsp) # 128 bit return value in xmm0 \n\
+ movq 0x10(%rsp),%rax # copy over to %rax and %rdx \n\
+ movq 0x18(%rsp),%rdx \n\
+ leaq dll_chain(%rip),%rcx # load address of dll_chain \n\
+ movq %rcx,0x28(%rsp) # and overwrite return address \n\
+ addq $0x20,%rsp \n\
+ popq %rbp \n\
+ ret \n\
+ .seh_endproc \n\
+");
+
+INIT_WRAPPER (std_dll_init)
+
+__attribute__ ((used, noinline)) static two_addr_t
+std_dll_init (struct func_info *func)
+#else
+__attribute__ ((used, noinline)) static two_addr_t
std_dll_init ()
+#endif
{
+#ifndef __x86_64__
struct func_info *func = (struct func_info *) __builtin_return_address (0);
+#endif
struct dll_info *dll = func->dll;
retchain ret;
@@ -284,26 +456,38 @@ std_dll_init ()
}
/* Set "arguments" for dll_chain. */
- ret.low = (long) dll->init;
- ret.high = (long) func;
+ ret.low = (uintptr_t) dll->init;
+ ret.high = (uintptr_t) func;
InterlockedDecrement (&dll->here);
+#ifndef __x86_64__
/* Kludge alert. Redirects the return address to dll_chain. */
- __asm__ __volatile__ (" \n\
- movl $dll_chain,4(%ebp) \n\
- ");
+ uintptr_t *volatile frame = (uintptr_t *) __builtin_frame_address (0);
+ frame[1] = (uintptr_t) dll_chain;
+#endif
return ret.ll;
}
/* Initialization function for winsock stuff. */
WSADATA NO_COPY wsadata;
-static long long __attribute__ ((used, noinline))
+
+#ifdef __x86_64__
+/* See above comment preceeding std_dll_init. */
+INIT_WRAPPER (wsock_init)
+
+__attribute__ ((used, noinline)) static two_addr_t
+wsock_init (struct func_info *func)
+#else
+__attribute__ ((used, noinline)) static two_addr_t
wsock_init ()
+#endif
{
static LONG NO_COPY here = -1L;
+#ifndef __x86_64__
struct func_info *func = (struct func_info *) __builtin_return_address (0);
+#endif
struct dll_info *dll = func->dll;
while (InterlockedIncrement (&here))
@@ -330,23 +514,23 @@ wsock_init ()
debug_printf ("szSystemStatus %s", wsadata.szSystemStatus);
debug_printf ("iMaxSockets %d", wsadata.iMaxSockets);
debug_printf ("iMaxUdpDg %d", wsadata.iMaxUdpDg);
- debug_printf ("lpVendorInfo %d", wsadata.lpVendorInfo);
wsock_started = 1;
}
}
+#ifndef __x86_64__
/* Kludge alert. Redirects the return address to dll_chain. */
- __asm__ __volatile__ (" \n\
- movl $dll_chain,4(%ebp) \n\
- ");
+ uintptr_t *volatile frame = (uintptr_t *) __builtin_frame_address (0);
+ frame[1] = (uintptr_t) dll_chain;
+#endif
InterlockedDecrement (&here);
volatile retchain ret;
/* Set "arguments for dll_chain. */
- ret.low = (long) dll_func_load;
- ret.high = (long) func;
+ ret.low = (uintptr_t) dll_func_load;
+ ret.high = (uintptr_t) func;
return ret.ll;
}
@@ -383,19 +567,16 @@ LoadDLLfunc (ReportEventW, 36, advapi32)
LoadDLLfunc (DnsQuery_A, 24, dnsapi)
LoadDLLfunc (DnsRecordListFree, 8, dnsapi)
-// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't support iphlpapi funcs
-LoadDLLfuncEx2 (GetAdaptersAddresses, 20, iphlpapi, 1, 50)
+LoadDLLfunc (GetAdaptersAddresses, 20, iphlpapi)
LoadDLLfunc (GetIfEntry, 4, iphlpapi)
LoadDLLfunc (GetIpAddrTable, 12, iphlpapi)
LoadDLLfunc (GetIpForwardTable, 12, iphlpapi)
LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
LoadDLLfunc (GetUdpTable, 12, iphlpapi)
-LoadDLLfuncEx (AttachConsole, 4, kernel32, 1)
-LoadDLLfuncEx (GetModuleHandleExW, 12, kernel32, 1)
+LoadDLLfuncEx (CancelSynchronousIo, 4, kernel32, 1)
+LoadDLLfunc (CreateSymbolicLinkW, 12, kernel32)
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
-LoadDLLfuncEx (GetSystemWow64DirectoryW, 8, kernel32, 1)
-LoadDLLfuncEx (GetVolumePathNamesForVolumeNameW, 16, kernel32, 1)
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
LoadDLLfunc (WNetCloseEnum, 4, mpr)