From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26309 invoked by alias); 17 Jul 2013 06:32:31 -0000 Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner@cygwin.com Mail-Followup-To: cygwin@cygwin.com Received: (qmail 26282 invoked by uid 89); 17 Jul 2013 06:32:30 -0000 X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_50,KHOP_RCVD_UNTRUST,KHOP_THREADED,MIME_QP_LONG_LINE,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,RDNS_NONE,SPF_HELO_PASS autolearn=no version=3.3.1 Received: from Unknown (HELO mailout2.w1.samsung.com) (210.118.77.12) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 17 Jul 2013 06:32:28 +0000 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MQ200JZKHZ6S130@mailout2.w1.samsung.com> for cygwin@cygwin.com; Wed, 17 Jul 2013 07:32:19 +0100 (BST) Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 52.FD.13793.37A36E15; Wed, 17 Jul 2013 07:32:19 +0100 (BST) Received: from fedinw7x64 ([106.109.9.113]) by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MQ2003HQI5U8B40@eusync4.samsung.com>; Wed, 17 Jul 2013 07:32:19 +0100 (BST) From: Fedin Pavel To: 'Andrew Schulman' , cygwin@cygwin.com References: <000001ce7e08$2b866830$82933890$%fedin@samsung.com> <4q4ut8had25hqmo8b0752i8asuv6ism2qh@4ax.com> <002901ce7f0a$9da99420$d8fcbc60$%fedin@samsung.com> In-reply-to: Subject: [PATCH] Fix optional variables in libargp Date: Wed, 17 Jul 2013 09:57:00 -0000 Message-id: <002601ce82b7$63229580$2967c080$%fedin@samsung.com> MIME-version: 1.0 Content-type: multipart/mixed; boundary="----=_NextPart_000_0027_01CE82D8.EA343580" X-Virus-Found: No X-SW-Source: 2013-07/txt/msg00339.txt.bz2 ------=_NextPart_000_0027_01CE82D8.EA343580 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 1744 Hello! > Okay, well I agree that this sounds like a good solution. For now you > have a workaround, and I'll be glad to consider a patch if you submit > one. Please take it. This is my experimental implementation which appears to be simpler than i suggested. Some details: this implementation adds explicit dllexport attribute to these 4 variables. This allows to look them up using GetProcAddress(). The dllexport attribute has to be added explicitly because when compiling an .exe file (without -shared switch) gcc does not mark externals as exportable by default. When building a .dll, all external symbols are marked as exportable by default, *UNLESS* we have at least one explicit dllexport specification, hence i surrounded this with #ifndef DLL_EXPORT, this definition is introduced by libtool when building a shared library. This implementation would not work in the following corner cases: a) .exe file uses some foo.dll library, which defines these variables and uses libargp - symbols are picked up only from .exe file itself. b) Building that foo.dll manually without DLL_EXPORT definition can get broken - the compiler will see dllexport attribute, and it will override the default behavior to make all externs exportable. I believe these cases are quite unusual so it's OK. Getting rid of these limitations would need more complex implementation with more changes. I have tested the implementation on x86-64 with RedHat's Prelink utility, and it works quite fine. i386 should work too, but please retest, just in case. Additionally, i added the second #ifdef _WIN32 in order to make the same thing working also for MinGW target. Kind regards, Pavel Fedin Expert Engineer Samsung Electronics Research center Russia ------=_NextPart_000_0027_01CE82D8.EA343580 Content-Type: application/octet-stream; name="libargp-20110921-fix-optional-variables.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="libargp-20110921-fix-optional-variables.diff" Content-length: 4155 diff -ru src/libargp-20110921.orig/gllib/argp.h src/libargp-20110921/gllib/= argp.h=0A= --- src/libargp-20110921.orig/gllib/argp.h 2011-09-23 03:31:26.000000000 +0= 500=0A= +++ src/libargp-20110921/gllib/argp.h 2013-07-15 12:03:51.616647900 +0500= =0A= @@ -64,6 +64,18 @@=0A= typedef int error_t;=0A= # define __error_t_defined=0A= #endif=0A= +=0A= +#ifndef DLL_EXPORT=0A= +#ifdef __CYGWIN__=0A= +#define __dllexport __declspec(dllexport)=0A= +#endif=0A= +#ifdef _WIN32=0A= +#define __dllexport __declspec(dllexport)=0A= +#endif=0A= +#endif=0A= +#ifndef __dllexport=0A= +#define __dllexport=0A= +#endif=0A= =0C=0A= #ifdef __cplusplus=0A= extern "C" {=0A= @@ -441,14 +453,14 @@=0A= option --version is added (unless the ARGP_NO_HELP flag is used), which= =0A= will print this string followed by a newline and exit (unless the=0A= ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. = */=0A= -extern const char *argp_program_version;=0A= +__dllexport extern const char *argp_program_version;=0A= =20=0A= /* If defined or set by the user program to a non-zero value, then a defau= lt=0A= option --version is added (unless the ARGP_NO_HELP flag is used), which= =0A= calls this function with a stream to print the version to and a pointer= to=0A= the current parsing state, and then exits (unless the ARGP_NO_EXIT flag= is=0A= used). This variable takes precedent over ARGP_PROGRAM_VERSION. */=0A= -extern void (*argp_program_version_hook) (FILE *__restrict __stream,=0A= +__dllexport extern void (*argp_program_version_hook) (FILE *__restrict __s= tream,=0A= struct argp_state *__restrict=0A= __state);=0A= =20=0A= @@ -457,12 +469,12 @@=0A= argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various=0A= standard help messages), embedded in a sentence that says something lik= e=0A= `Report bugs to ADDR.'. */=0A= -extern const char *argp_program_bug_address;=0A= +__dllexport extern const char *argp_program_bug_address;=0A= =20=0A= /* The exit status that argp will use when exiting due to a parsing error.= =0A= If not defined or set by the user program, this defaults to EX_USAGE fr= om=0A= . */=0A= -extern error_t argp_err_exit_status;=0A= +__dllexport extern error_t argp_err_exit_status;=0A= =0C=0A= /* Flags for argp_help. */=0A= #define ARGP_HELP_USAGE 0x01 /* a Usage: message. */=0A= diff -ru src/libargp-20110921.orig/gllib/argp-parse.c src/libargp-20110921/= gllib/argp-parse.c=0A= --- src/libargp-20110921.orig/gllib/argp-parse.c 2011-09-23 03:31:26.000000= 000 +0500=0A= +++ src/libargp-20110921/gllib/argp-parse.c 2013-07-15 11:39:49.690236100 += 0500=0A= @@ -64,6 +64,42 @@=0A= /* EZ alias for ARGP_ERR_UNKNOWN. */=0A= #define EBADKEY ARGP_ERR_UNKNOWN=0A= =0C=0A= +/* Windows does not support things like weak symbols, neither it will merg= e two=0A= + external symbols. In order to make our optional variables working, we h= ave=0A= + to do this trick. What we do here is looking up respective variables in= =0A= + main .exe file and patching our versions with correct pointers=0A= + Note that the whole thing relies on these variables being declared with= =0A= + __declspec(dllexport). */=0A= +#ifdef DLL_EXPORT=0A= +=0A= +#include =0A= +=0A= +#ifdef __i386__=0A= +#define PREFIX "_"=0A= +#else=0A= +#define PREFIX=0A= +#endif=0A= +=0A= +#define PatchPtr(var) \=0A= + p =3D (void **)GetProcAddress(NULL, PREFIX #var ); \=0A= + if (p) var =3D *p;=0A= +=0A= +#define PatchInt(var) \=0A= + i =3D (int *)GetProcAddress(NULL, PREFIX #var ); \=0A= + if (i) var =3D *i;=0A= +=0A= +static void __attribute__((constructor)) patch_vars(void)=0A= +{=0A= + void **p;=0A= + int *i;=0A= +=0A= + PatchPtr(argp_program_version);=0A= + PatchPtr(argp_program_version_hook);=0A= + PatchPtr(argp_program_bug_address);=0A= + PatchInt(argp_err_exit_status);=0A= +}=0A= +#endif=0A= +=0A= /* Default options. */=0A= =20=0A= /* When argp is given the --HANG switch, _ARGP_HANG is set and argp will s= leep=0A= =0A= ------=_NextPart_000_0027_01CE82D8.EA343580 Content-Type: text/plain; charset=us-ascii Content-length: 218 -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple ------=_NextPart_000_0027_01CE82D8.EA343580--