From kde-cygwin Thu Aug 28 19:59:34 2003 From: "Ralf Habacker" Date: Thu, 28 Aug 2003 19:59:34 +0000 To: kde-cygwin Subject: [PATCH] gcc3/ld patch for direct-linking-to-dll and auto-import X-MARC-Message: https://marc.info/?l=kde-cygwin&m=106210083723368 MIME-Version: 1 Content-Type: multipart/mixed; boundary="------=_NextPart_000_004E_01C36DAF.AACC0E70" This is a multi-part message in MIME format. ------=_NextPart_000_004E_01C36DAF.AACC0E70 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi while compiling trolltechs qt/xfree library with gcc3 (3.2x) on cygwin I recognized, that the auto-import stuff in combination of recent ld does not work in case of const variables in a dll when using direct linking to a dll, because gcc put those variables into a readonly, that means the .text section. The patch and a testcase is appended. A documentation could be found in the patch file. A binary update (only containing ld) could be found here: http://kde-cygwin.sourceforge.net/snapshots/ld-gcc3-const-var-patch.tar.bz2 Cheers Ralf ------=_NextPart_000_004E_01C36DAF.AACC0E70 Content-Type: application/octet-stream; name="ld-gcc3-const-var-patch-testcase.tar.bz2" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="ld-gcc3-const-var-patch-testcase.tar.bz2" QlpoOTFBWSZTWfhfsGAAAgX/xNxyBABef/+ffeYI3f/v3+oACAAIAAhQA152V1O07ZToEkimSfpN E9MhPSbUyZExHqZGDQACabRqekaYZE0BRNH6oAAAAAyAaA0AaABKamhU/VD0jINDRoNAADQAAAAN A4BhGE0xDAIBkAMI0yZMIwENBIkgE0A1DU2ho0hk00ADTTCaeoBoHpNS+vd0dT7NwJi/1gyBIdYk kb+h9+TpCYIWnSRJRMjZCgBDIB1JGkGGwbIAH+4vxPTxtUuSvSTyg8YraeBZiX+aScP7SqoQ+ZkF MSnBhxyVsGScaBl7N55x2IIxTriktn8iv8mSiiHnksTmo6zLbi4NDezT6ktyg93aZ6/GZtNymxgC P7vCzAP97uLuusN+FRJEzREwRjBrCkkgSbcJByVxMma5c16axIDG4Lr3c8JZlmS7vQmPq4e/Wpvv dfwYdUDYGxkTMJmMpvMdIXlOgqgQzOGGU3SFUsXoNHcCgQqYMjNQOjIecuUsOHMzKRz2e5xsoxoo r3bQU8y5UhYwTLMHrov33mAECgCgXZkdV5ib20pklrdScjrTIpJ47kKuiIRqywXF/JuM6JaKYBoF obMGMmaOCROyHoBJ6hyJzOAdgGnkwBn3Bi9IrLMXNHTASyVylCWPlBoMD70KuPgMQqVoK6PwsnIw 5o0S51G70FCI3z1FAgzrNeSjt7WDdkkDtV9Qagxm6Eg6yzz5l+urhRt4OyP2bHtmJb2ENQkaOLmC ZBhVpgx4+k57ogWuoxhynPNrLJqCCdMcwa9UHo3fB2UDDHqSvHXvPEXGFj7C1QpAutNQVf+W3szD 48qsZJBjXG/dFYqTLG2Jowqzg7mrkbyMxPfrKUKmWK4rCcHUM+mU3ZGU6BlYWZIxq8hsGiwipbep XK2+sI03DIeILjfVV4YvQCyu5Awh+9apMIq3jc1q1ZFpIlal6hNPeJa60r+yVYUrWEr0yM6kLjEi UADBhKwtHnLZ7sIkbU6ymQrvq03gkpZlnByieZF9gbsoQrBQKuipjYASsAwfWUUnV8BKDloRmACh IcBYLxm649d5VCVobRCUAMQ64CAFVwFXC02eJugMCB1EKhVIwMFh7yltBmWC6fR3Bs2mShbDOQcO 53KUBFFBXiCbCLTwSYQJL/i7kinChIfC/YMA ------=_NextPart_000_004E_01C36DAF.AACC0E70 Content-Type: application/octet-stream; name="ld-gcc3-const-var-patch.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ld-gcc3-const-var-patch.patch" Index: pe-dll.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvs/src/src/ld/pe-dll.c,v=0A= retrieving revision 1.60=0A= diff -u -3 -p -B -r1.60 pe-dll.c=0A= --- pe-dll.c 17 Jul 2003 15:47:49 -0000 1.60=0A= +++ pe-dll.c 28 Aug 2003 19:45:39 -0000=0A= @@ -120,6 +120,44 @@=0A= =0A= See also: ld/emultempl/pe.em. */=0A= =0A= +/* gcc3 support for direct-linking-to-dll and auto-import =0A= + =0A= + Background:=0A= + =0A= + gcc2/3 stores regular initialized variables in the .data and = uninitialized =0A= + variables in the .bss section. While gcc2 stores constant variables = also in =0A= + the .data section, gcc3 stores constant variables in the .text = section. =0A= + =0A= + This is no problem when using import libraries, but using the = direct-linking-=0A= + to-dll feature with gcc3 compiled sources let the auto-import stuff = fail because =0A= + data variables are only expected to be in the .data section, which = results in =0A= + not auto-imported data variables; they are linked as functions and = this results =0A= + in runtime segfaults.=0A= + =0A= + How it works: =0A= + =0A= + The gcc3 support for direct-linking-to-dll and auto-import remove = this =0A= + limitation in two steps: =0A= + 1. On linking a dll exported constant variables are prefixed with a = string=0A= + (CONST_KEY), which could not be emulated by regular c++ symbols = to avoid =0A= + unwanted triggering of the auto-import stuff. =0A= + 2. On linking a dll or application with another dll containing = exported const =0A= + symbols ld searches for such prefixed symbols and auto-import = this symbols =0A= + like regular data symbols.=0A= + =0A= + Example: =0A= + const int constvar =3D 2; =3D> .const$constvar =0A= + =0A= + class test {=0A= + static const int staticconstvar; =3D> = .const$_ZN4test14staticconstvarE=0A= + }=0A= +*/ =0A= + =0A= +/* name prefix for gcc3 direct-linking-to-dll and auto-import support */=0A= +#define CONST_KEY ".const$"=0A= +#define CONST_KEY_SIZE 7=0A= +=0A= +=0A= static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info = *);=0A= =0A= /* For emultempl/pe.em. */=0A= @@ -536,11 +574,13 @@ process_def_file (bfd *abfd ATTRIBUTE_UN=0A= {=0A= asymbol **symbols;=0A= int nsyms, symsize;=0A= + asection *section_text;=0A= =0A= symsize =3D bfd_get_symtab_upper_bound (b);=0A= symbols =3D xmalloc (symsize);=0A= nsyms =3D bfd_canonicalize_symtab (b, symbols);=0A= -=0A= + section_text =3D bfd_get_section_by_name (b, ".text"); =0A= + =0A= for (j =3D 0; j < nsyms; j++)=0A= {=0A= /* We should export symbols which are either global or not=0A= @@ -571,9 +611,25 @@ process_def_file (bfd *abfd ATTRIBUTE_UN=0A= if (auto_export (b, pe_def_file, sn))=0A= {=0A= def_file_export *p;=0A= - p=3Ddef_file_add_export (pe_def_file, sn, 0, -1);=0A= - /* Fill data flag properly, from dlltool.c. */=0A= - p->flag_data =3D !(symbols[j]->flags & BSF_FUNCTION);=0A= +=0A= + /* prefix CONST_KEY to symbolname in case of data symbols =0A= + pointing to the text segment (const vars) to support auto-import = */ =0A= + if (!(symbols[j]->flags & BSF_FUNCTION) && =0A= + symbols[j]->section =3D=3D section_text) =0A= + {=0A= + char *prefix =3D CONST_KEY; =0A= + char *tmp =3D xmalloc (strlen(sn) + strlen(prefix) + 1);=0A= + strcpy(tmp,prefix); =0A= + strcat(tmp,sn);=0A= + p=3Ddef_file_add_export (pe_def_file, tmp, sn, -1);=0A= + p->flag_data =3D 1; =0A= + }=0A= + else =0A= + {=0A= + p=3Ddef_file_add_export (pe_def_file, sn, 0, -1);=0A= + /* Fill data flag properly, from dlltool.c. */=0A= + p->flag_data =3D !(symbols[j]->flags & BSF_FUNCTION);=0A= + }=0A= }=0A= }=0A= }=0A= @@ -2246,17 +2303,23 @@ pe_dll_generate_implib (def_file *def, c=0A= =0A= for (i =3D 0; i < def->num_exports; i++)=0A= {=0A= - /* The import library doesn't know about the internal name. */=0A= - char *internal =3D def->exports[i].internal_name;=0A= bfd *n;=0A= -=0A= - def->exports[i].internal_name =3D def->exports[i].name;=0A= - n =3D make_one (def->exports + i, outarch);=0A= - n->next =3D head;=0A= - head =3D n;=0A= - def->exports[i].internal_name =3D internal;=0A= - }=0A= -=0A= + /* the prefix CONST_KEY used for const var symbols must not be = put into the import library */ =0A= + if (strncmp(def->exports[i].name,CONST_KEY,CONST_KEY_SIZE) =3D=3D = 0) {=0A= + char *external =3D def->exports[i].name;=0A= + def->exports[i].name =3D def->exports[i].internal_name;=0A= + n =3D make_one (def->exports + i, outarch);=0A= + def->exports[i].name =3D external;=0A= + } else {=0A= + /* The import library doesn't know about the internal name. */=0A= + char *internal =3D def->exports[i].internal_name;=0A= + def->exports[i].internal_name =3D def->exports[i].name;=0A= + n =3D make_one (def->exports + i, outarch);=0A= + def->exports[i].internal_name =3D internal;=0A= + }=0A= + n->next =3D head;=0A= + head =3D n;=0A= + }=0A= ar_tail =3D make_tail (outarch);=0A= =0A= if (ar_head =3D=3D NULL || ar_tail =3D=3D NULL)=0A= @@ -2567,26 +2630,32 @@ pe_implied_import_dll (const char *filen=0A= def_file_import *imp;=0A= /* Pointer to the function address vector. */=0A= unsigned long func_rva =3D pe_as32 (erva + exp_funcbase + i * 4);=0A= - int is_data =3D 0;=0A= + char *sym_name =3D erva + name_rva;=0A= =0A= /* Skip unwanted symbols, which are=0A= exported in buggy auto-import releases. */=0A= - if (strncmp (erva + name_rva, "_nm_", 4) !=3D 0)=0A= + if (strncmp (sym_name, "_nm_", 4) !=3D 0)=0A= {=0A= - /* is_data is true if the address is in the data or bss segment. */=0A= - is_data =3D=0A= - (func_rva >=3D data_start && func_rva < data_end)=0A= - || (func_rva >=3D bss_start && func_rva < bss_end);=0A= -=0A= - imp =3D def_file_add_import (pe_def_file, erva + name_rva,=0A= + /* handle const var auto-importing with direct linking to dll */ =0A= + if (strncmp (sym_name, CONST_KEY, CONST_KEY_SIZE) =3D=3D 0 ) =0A= + {=0A= + imp =3D def_file_add_import (pe_def_file, sym_name, =0A= + dll_name, i, sym_name+CONST_KEY_SIZE);=0A= + imp->data =3D 1;=0A= + }=0A= + else =0A= + {=0A= + imp =3D def_file_add_import (pe_def_file, sym_name,=0A= dll_name, i, 0);=0A= - /* Mark symbol type. */=0A= - imp->data =3D is_data;=0A= -=0A= - if (pe_dll_extra_pe_debug)=0A= - printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",=0A= - __FUNCTION__, dll_name, erva + name_rva,=0A= - func_rva, is_data ? "(data)" : "");=0A= + /* symbol is data if the address is in the data or bss segment. = */=0A= + imp->data =3D=0A= + (func_rva >=3D data_start && func_rva < data_end)=0A= + || (func_rva >=3D bss_start && func_rva < bss_end);=0A= + }=0A= + if (pe_dll_extra_pe_debug)=0A= + printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",=0A= + __FUNCTION__, dll_name, sym_name,=0A= + func_rva, imp->data ? "(data)" : "");=0A= }=0A= }=0A= =0A= ------=_NextPart_000_004E_01C36DAF.AACC0E70 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kde-cygwin mailing list kde-cygwin@mail.kde.org http://mail.kde.org/mailman/listinfo/kde-cygwin ------=_NextPart_000_004E_01C36DAF.AACC0E70--