D.gnu - [Bug 100] New: add shared lib support
- gdc-bugzilla gdcproject.org (748/748) Feb 01 2014 http://bugzilla.gdcproject.org/show_bug.cgi?id=100
http://bugzilla.gdcproject.org/show_bug.cgi?id=100 Summary: add shared lib support Classification: Unclassified Product: GDC Version: development Platform: x86 OS/Version: Other Status: NEW Severity: major Priority: Normal Component: gdc AssignedTo: ibuclaw gdcproject.org ReportedBy: slavo5150 yahoo.com This was migrated from https://bitbucket.org/goshawk/gdc/issue/166/add-shared-lib-support Anonymous created an issue 2011-03-17 **************************************** I build a dynamic project, the libgphobos.a, libgdruntime.a is not build with -fPIC, I think we should create a libgphobos_shared.a and libgdruntime_shared.a . Anonymous - 2011-03-21 **************************************** Hello, Can any body give a tip how to do this !!!!!!!!!!!!!!! or there already is a document , or I am wrong gdc already can build .so file with current libgphobos.a !!!!!!! any body please give me a response . Daniel Green - 2011-03-22 **************************************** I have never tried. I can tell you that a static library does not prohibit a project from using shared libraries. The elf format and linker take care of everything so all symbols resolve to a single copy(usually the copy inside your program). That was the conclusion I came to several years ago. I'm sure there are other advantages. I have built a project utilizing that fact with D before. As long as you can get the druntime and phobos to compile with -fPIC, then creating a shared library from that output should be relatively simple(Do a search for converting static to shared). I would also search the newsgroup for others who have attempted this. I've heard reference to it before. Anonymous - 2011-03-22 **************************************** Thank for this valuable answer . I know the DRuntime & phobos is patch before GDC build it , I can't find where is the posix.mak in gdc source package before I run ../configure --enable-languages=d --enable-checking=release --disable-shared && make . one more question , should I use ../configure --enable-languages=d --enable-checking=release --enable-shared Anonymous - 2011-03-22 **************************************** I use export DGLAGS=-fPIC, then catch this error . /web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/./gcc/gdc -B/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/./gcc/ -B/usr/local/x86_64-unknown-linux-gnu/bin/ -B/usr/local/x86_64-unknown-linux-gnu/lib/ -isystem /usr/local/x86_64-unknown-linux-gnu/include -isystem /usr/local/x86_64-unknown-linux-gnu/sys-include -m32 -o rt/adi.o -fPIC -fversion=GC_Use_Alloc_MMap -fversion=GC_Use_Stack_GLibC -fversion=GC_Use_Data_Fixed -nostdinc -pipe -fdeprecated -I ../../../../libphobos -I ./x86_64-unknown-linux-gnu -m32 -c ../../../../libphobos/rt/adi.d ../../../../libphobos/rt/adi.d: Assembler messages: ../../../../libphobos/rt/adi.d:474: Warning: missing operand; zero assumed ../../../../libphobos/rt/adi.d:475: Warning: missing operand; zero assumed ../../../../libphobos/rt/adi.d:477: Warning: missing operand; zero assumed ../../../../libphobos/rt/adi.d:478: Warning: missing operand; zero assumed ../../../../libphobos/rt/adi.d:536: Warning: missing operand; zero assumed ../../../../libphobos/rt/adi.d:537: Warning: missing operand; zero assumed /web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/./gcc/gdc -B/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/./gcc/ -B/usr/local/x86_64-unknown-linux-gnu/bin/ -B/usr/local/x86_64-unknown-linux-gnu/lib/ -isystem /usr/local/x86_64-unknown-linux-gnu/include -isystem /usr/local/x86_64-unknown-linux-gnu/sys-include -m32 -o rt/arrayassign.o -fPIC -fversion=GC_Use_Alloc_MMap -fversion=GC_Use_Stack_GLibC -fversion=GC_Use_Data_Fixed -nostdinc -pipe -fdeprecated -I ../../../../libphobos -I ./x86_64-unknown-linux-gnu -m32 -c ../../../../libphobos/rt/arrayassign.d /web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/./gcc/gdc -B/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/./gcc/ -B/usr/local/x86_64-unknown-linux-gnu/bin/ -B/usr/local/x86_64-unknown-linux-gnu/lib/ -isystem /usr/local/x86_64-unknown-linux-gnu/include -isystem /usr/local/x86_64-unknown-linux-gnu/sys-include -m32 -o rt/arraybyte.o -fPIC -fversion=GC_Use_Alloc_MMap -fversion=GC_Use_Stack_GLibC -fversion=GC_Use_Data_Fixed -nostdinc -pipe -fdeprecated -I ../../../../libphobos -I ./x86_64-unknown-linux-gnu -m32 -c ../../../../libphobos/rt/arraybyte.d ../../../../libphobos/rt/arraybyte.d: In function ‘_arraySliceExpAddSliceAssign_g’: ../../../../libphobos/rt/arraybyte.d:220: error: PIC register ‘ebx’ clobbered in ‘asm’ ../../../../libphobos/rt/arraybyte.d:222: error: PIC register ‘ebx’ clobbered in ‘asm’ ../../../../libphobos/rt/arraybyte.d:223: error: PIC register ‘ebx’ clobbered in ‘asm’ ../../../../libphobos/rt/arraybyte.d: In function ‘_arraySliceExpMinSliceAssign_g’: ../../../../libphobos/rt/arraybyte.d:1039: error: PIC register ‘ebx’ clobbered in ‘asm’ ../../../../libphobos/rt/arraybyte.d:1041: error: PIC register ‘ebx’ clobbered in ‘asm’ ../../../../libphobos/rt/arraybyte.d:1042: error: PIC register ‘ebx’ clobbered in ‘asm’ make[6]: *** [rt/arraybyte.o] Error 1 make[6]: Leaving directory `/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/x86_64-unknown-linux-gnu/32/libphobos' make[5]: *** [all] Error 2 make[5]: Leaving directory `/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/x86_64-unknown-linux-gnu/32/libphobos' make[4]: *** [multi-do] Error 1 make[4]: Leaving directory `/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/x86_64-unknown-linux-gnu/libphobos' make[3]: *** [all-multi] Error 2 make[3]: Leaving directory `/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/x86_64-unknown-linux-gnu/libphobos' make[2]: *** [all] Error 2 make[2]: Leaving directory `/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir/x86_64-unknown-linux-gnu/libphobos' make[1]: *** [all-target-libphobos] Error 2 make[1]: Leaving directory `/web/pool/source_storage/gdc/dev/gcc-4.4.5/objdir' make: *** [all] Error 2 Anonymous - 2011-09-13 **************************************** Here is a patch for gdc with dmd 2.054 (until revision b0a9ef534877). It patches d-asm-i386.h, core/cpuid.d, core/thread.d, rt/arraybyte.d, rt/arrayint.d, std/cpuid.d. I tested it with gcc 4.4.5 and it let me compile gdc version 2 (or actually phobos2) with -fPIC so you can create shared objects on x86_64 platforms. The compilation errors with ebx clobbering are a result of the 32bit pic implentation. In 32bit code the ebx register is the pic-register and cannot be marked clobbered. That is what is fixed in d-asm-i386.h, now gdc doesn't tell gcc that ebx gets clobbered if compiling 32bit PIC code. This means that _you_ have to make sure that the value of ebx is saved and restored (this is adressed in the patches of phobos2 and druntime files), wich is what you'd have to do in C too if the PIC regiser get clobbered. I'm not sure if I found all places where the ebx register is used in phobos2/druntime there are probably many more files that need to be patched. Also I had issues when compiling with -funittest, but I don't know if this is related to the patch or something else. PS: I'm not entirely sure but it shouln't matter if you apply the patch before or after calling ./gcc/d/setup-gdc.sh -v2 PS2: HowTo: copy the patch to a new file (lets call it gdc-dmd-2054-pic.patch) in gcc-<version> (the main directory) and call "patch -p0 < gdc-dmd-2054-pic.patch". Daniel Edwards diff -Naru gcc-van/d/d-asm-i386.h gcc/d/d-asm-i386.h --- gcc-van/d/d-asm-i386.h 2011-09-12 17:36:19.000000000 +0200 +++ gcc/d/d-asm-i386.h 2011-09-12 17:50:09.000000000 +0200 -2181,7 +2181,9 if (op == Op_cpuid) { asmcode->clbregs[Reg_EAX] = 1; - asmcode->clbregs[Reg_EBX] = 1; + // pic & 32bit : EBX must not be (marked) clobbered, it is the pic register + if (!global.params.pic || global.params.isX86_64) + asmcode->clbregs[Reg_EBX] = 1; asmcode->clbregs[Reg_ECX] = 1; asmcode->clbregs[Reg_EDX] = 1; } -2265,7 +2267,11 { Reg clbr_reg = (Reg) regInfo[operand->reg].baseReg; if (clbr_reg != Reg_Invalid) - asmcode->clbregs[clbr_reg] = 1; + { + // pic & 32bit : EBX must not be (marked) clobbered, it is the pic register + if (global.params.isX86_64 || !global.params.pic || clbr_reg != Reg_EBX) + asmcode->clbregs[clbr_reg] = 1; + } } if (opTakesLabel()/*opInfo->takesLabel()*/) insnTemplate->writebyte('*'); diff -Naru gcc-van/d/druntime/core/cpuid.d gcc/d/druntime/core/cpuid.d --- gcc-van/d/druntime/core/cpuid.d 2011-09-12 20:51:06.000000000 +0200 +++ gcc/d/druntime/core/cpuid.d 2011-09-12 20:58:09.000000000 +0200 -379,12 +379,16 uint numinfos = 1; do { asm { + mov EDI, EBX; + mov EAX, 2; cpuid; mov a, EAX; mov a+4, EBX; mov a+8, ECX; mov a+12, EDX; + + mov EBX, EDI; } if (firstTime) { if (a[0]==0x0000_7001 && a[3]==0x80 && a[1]==0 && a[2]==0) { -421,12 +425,16 for(;;) { uint a, b, number_of_sets; asm { + mov EDI, EBX; + mov EAX, 4; mov ECX, cachenum; cpuid; mov a, EAX; mov b, EBX; mov number_of_sets, ECX; + + mov EBX, EDI; } ++cachenum; if ((a&0x1F)==0) break; // no more caches -459,12 +467,16 { uint c5, c6, d6; asm { + mov EDI, EBX; + mov EAX, 0x8000_0005; // L1 cache cpuid; // EAX has L1_TLB_4M. // EBX has L1_TLB_4K // EDX has L1 instruction cache mov c5, ECX; + + mov EBX, EDI; } datacache[0].size = ( (c5>>24) & 0xFF); -476,18 +488,26 ubyte numcores = 1; if (max_extended_cpuid >=0x8000_0008) { asm { + mov EDI, EBX; + mov EAX, 0x8000_0008; cpuid; mov numcores, CL; + + mov EBX, EDI; } ++numcores; if (numcores>maxCores) maxCores = numcores; } asm { + mov EDI, EBX; + mov EAX, 0x8000_0006; // L2/L3 cache cpuid; mov c6, ECX; // L2 cache info mov d6, EDX; // L3 cache info + + mov EBX, EDI; } immutable ubyte [] assocmap = [ 0, 1, 2, 0, 4, 0, 8, 0, 16, 0, 32, 48, 64, 96, 128, 0xFF ]; -511,6 +531,8 uint a, b, c, d; do { asm { + mov EDI, EBX; + mov EAX, 0x0B; mov ECX, level; cpuid; -518,6 +540,8 mov b, EBX; mov c, ECX; mov d, EDX; + + mov EBX, EDI; } if (b!=0) { // I'm not sure about this. The docs state that there -539,16 +563,35 { char * venptr = vendorID.ptr; uint a, b, c, d, a2; + version(D_InlineAsm_X86) { - asm { - mov EAX, 0; - cpuid; - mov a, EAX; - mov EAX, venptr; - mov [EAX], EBX; - mov [EAX + 4], EDX; - mov [EAX + 8], ECX; + version(D_PIC) { + asm + { + mov EDI, EBX; + + mov EAX, 0; + cpuid; + mov a, EAX; + mov EAX, venptr; + mov [EAX], EBX; + mov [EAX + 4], EDX; + mov [EAX + 8], ECX; + + mov EBX, EDI; + } + } else { + asm + { + mov EAX, 0; + cpuid; + mov a, EAX; + mov EAX, venptr; + mov [EAX], EBX; + mov [EAX + 4], EDX; + mov [EAX + 8], ECX; + } } } else version(D_InlineAsm_X86_64) -563,36 +606,51 mov [RAX + 8], ECX; } } + asm { + mov EDI, EBX; + mov EAX, 0x8000_0000; cpuid; mov a2, EAX; + + mov EBX, EDI; } + max_cpuid = a; max_extended_cpuid = a2; - probablyIntel = vendorID == "GenuineIntel"; probablyAMD = vendorID == "AuthenticAMD"; uint apic = 0; // brand index, apic id + asm { + mov EDI, EBX; + mov EAX, 1; // model, stepping cpuid; mov a, EAX; mov apic, EBX; mov c, ECX; mov d, EDX; + + mov EBX, EDI; } + features = d; miscfeatures = c; amdfeatures = 0; amdmiscfeatures = 0; if (max_extended_cpuid >= 0x8000_0001) { asm { + mov EDI, EBX; + mov EAX, 0x8000_0001; cpuid; mov c, ECX; mov d, EDX; + + mov EBX, EDI; } amdmiscfeatures = c; amdfeatures = d; -610,9 +668,13 if (!probablyIntel && max_extended_cpuid >= 0x8000_0008) { // determine max number of cores for AMD asm { + mov EDI, EBX; + mov EAX, 0x8000_0008; cpuid; mov c, ECX; + + mov EBX, EDI; } uint apicsize = (c>>12) & 0xF; if (apicsize == 0) { -630,28 +692,59 char *procptr = processorNameBuffer.ptr; version(D_InlineAsm_X86) { - asm { - push ESI; - mov ESI, procptr; - mov EAX, 0x8000_0002; - cpuid; - mov [ESI], EAX; - mov [ESI+4], EBX; - mov [ESI+8], ECX; - mov [ESI+12], EDX; - mov EAX, 0x8000_0003; - cpuid; - mov [ESI+16], EAX; - mov [ESI+20], EBX; - mov [ESI+24], ECX; - mov [ESI+28], EDX; - mov EAX, 0x8000_0004; - cpuid; - mov [ESI+32], EAX; - mov [ESI+36], EBX; - mov [ESI+40], ECX; - mov [ESI+44], EDX; - pop ESI; + version(D_PIC) + { + asm + { + push EBX; + push ESI; + mov ESI, procptr; + mov EAX, 0x8000_0002; + cpuid; + mov [ESI], EAX; + mov [ESI+4], EBX; + mov [ESI+8], ECX; + mov [ESI+12], EDX; + mov EAX, 0x8000_0003; + cpuid; + mov [ESI+16], EAX; + mov [ESI+20], EBX; + mov [ESI+24], ECX; + mov [ESI+28], EDX; + mov EAX, 0x8000_0004; + cpuid; + mov [ESI+32], EAX; + mov [ESI+36], EBX; + mov [ESI+40], ECX; + mov [ESI+44], EDX; + pop ESI; + pop EBX; + } + } else { + asm + { + push ESI; + mov ESI, procptr; + mov EAX, 0x8000_0002; + cpuid; + mov [ESI], EAX; + mov [ESI+4], EBX; + mov [ESI+8], ECX; + mov [ESI+12], EDX; + mov EAX, 0x8000_0003; + cpuid; + mov [ESI+16], EAX; + mov [ESI+20], EBX; + mov [ESI+24], ECX; + mov [ESI+28], EDX; + mov EAX, 0x8000_0004; + cpuid; + mov [ESI+32], EAX; + mov [ESI+36], EBX; + mov [ESI+40], ECX; + mov [ESI+44], EDX; + pop ESI; + } } } else version(D_InlineAsm_X86_64) diff -Naru gcc-van/d/druntime/core/thread.d gcc/d/druntime/core/thread.d --- gcc-van/d/druntime/core/thread.d 2011-09-12 17:36:19.000000000 +0200 +++ gcc/d/druntime/core/thread.d 2011-09-12 18:52:49.000000000 +0200 -588,25 +588,48 } else version ( D_InlineAsm_X86_64 ) { - asm - { - // Not sure what goes here, popad is invalid in 64 bit code - pop RAX ; // 16 byte align the stack - pop R15 ; - pop R14 ; - pop R13 ; - pop R12 ; - pop R11 ; - pop R10 ; - pop R9 ; - pop R8 ; - pop RBP ; - pop RDI ; - pop RSI ; - pop RDX ; - pop RCX ; - pop RBX ; - pop RAX ; + version (D_PIC) { + asm + { + // Not sure what goes here, popad is invalid in 64 bit code + pop RAX ; // 16 byte align the stack + pop R15 ; + pop R14 ; + pop R13 ; + pop R12 ; + pop R11 ; + pop R10 ; + pop R9 ; + pop R8 ; + //pop RBP ; // Breaks compilation with -fPIC + pop RDI ; + pop RSI ; + pop RDX ; + pop RCX ; + pop RBX ; + pop RAX ; + } + } else { + asm + { + // Not sure what goes here, popad is invalid in 64 bit code + pop RAX ; // 16 byte align the stack + pop R15 ; + pop R14 ; + pop R13 ; + pop R12 ; + pop R11 ; + pop R10 ; + pop R9 ; + pop R8 ; + pop RBP ; + pop RDI ; + pop RSI ; + pop RDX ; + pop RCX ; + pop RBX ; + pop RAX ; + } } } else version( GNU ) diff -Naru gcc-van/d/druntime/rt/arraybyte.d gcc/d/druntime/rt/arraybyte.d --- gcc-van/d/druntime/rt/arraybyte.d 2011-09-12 17:36:19.000000000 +0200 +++ gcc/d/druntime/rt/arraybyte.d 2011-09-12 20:29:38.000000000 +0200 -210,6 +210,8 auto n = aptr + (a.length & ~3); asm { + push EBX; + mov ESI, aptr; mov EDI, n; mov EAX, bptr; -232,6 +234,8 mov aptr, ESI; mov bptr, EAX; + + pop EBX; } } -1029,6 +1033,8 auto n = aptr + (a.length & ~3); asm { + push EBX; + mov ESI, aptr; mov EDI, n; mov EAX, bptr; -1051,6 +1057,8 mov aptr, ESI; mov bptr, EAX; + + pop EBX; } } } diff -Naru gcc-van/d/druntime/rt/arrayint.d gcc/d/druntime/rt/arrayint.d --- gcc-van/d/druntime/rt/arrayint.d 2011-09-12 17:36:19.000000000 +0200 +++ gcc/d/druntime/rt/arrayint.d 2011-09-12 20:32:18.000000000 +0200 -183,6 +183,8 asm { + push EBX; + mov ESI, aptr; mov EDI, n; mov EAX, bptr; -203,6 +205,8 mov aptr, ESI; mov bptr, EAX; + + pop EBX; } } } -554,6 +558,8 asm { + push EBX; + mov ESI, aptr; mov EDI, n; mov EDX, value; -571,6 +577,8 jb start386; mov aptr, ESI; + + pop EBX; } } } -928,6 +936,8 asm { + push EBX; + mov ESI, aptr; mov EDI, n; mov EAX, bptr; -948,6 +958,8 mov aptr, ESI; mov bptr, EAX; + + pop EBX; } } } -1477,6 +1489,8 asm { + push EBX; + mov ESI, aptr; mov EDI, n; mov EDX, value; -1494,6 +1508,8 jb start386; mov aptr, ESI; + + pop EBX; } } } diff -Naru gcc-van/d/phobos2/std/cpuid.d gcc/d/phobos2/std/cpuid.d --- gcc-van/d/phobos2/std/cpuid.d 2011-09-12 17:36:20.000000000 +0200 +++ gcc/d/phobos2/std/cpuid.d 2011-09-12 20:17:57.000000000 +0200 -235,12 +235,16 // puts the vendor string into dst asm { + mov EDI, EBX; + mov EAX, 0 ; cpuid ; mov EAX, dst ; mov [EAX], EBX ; mov [EAX+4], EDX ; mov [EAX+8], ECX ; + + mov EBX, EDI; } } -251,6 +255,8 // puts the processor string into dst asm { + push EBX; + mov EAX, 0x8000_0000 ; cpuid ; cmp EAX, 0x8000_0004 ; -277,6 +283,8 mov [EDI+44], EDX ; pop EDI ; PSLabel: ; + + pop EBX; } if (buffer[0] == char.init) // no support -291,6 +299,8 uint f,m,e,a,s; asm { + mov EDI, EBX; + mov EAX, 0 ; cpuid ; cmp EAX, 1 ; -312,6 +322,8 mov e, EDX ; FeatLabel2: + + mov EBX, EDI; ; } flags = f; -327,6 +339,8 ubyte b = 0; asm { + mov EDI, EBX; + mov EAX, 0 ; cpuid ; cmp EAX, 4 ; -337,6 +351,8 mov n, EAX ; mov b, 1 ; IntelSingle: ; + + mov EBX, EDI; } if (b != 0) { -355,6 +371,8 ubyte b = 0; asm { + mov EDI, EBX; + mov EAX, 0x8000_0000 ; cpuid ; cmp EAX, 0x8000_0008 ; -364,6 +382,8 mov n, CL ; mov b, 1 ; AMDSingle: ; + + mov EBX, EDI; } if (b != 0) { Anonymous - 2011-09-13 **************************************** Sorry for the double post but it seems that in dmd 2.055 global.params.isX86_64 changed to global.params.is64bit in d-asm-i386.h Daniel Edwards siretty - 2011-09-13 **************************************** https://bitbucket.org/goshawk/gdc/issue/4/libgphobos2-doesnt-respect-the-enable) was marked as a duplicate of this issue. Iain Buclaw - 2011-09-26 **************************************** -- Configure bugmail: http://bugzilla.gdcproject.org/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are watching all bug changes.
Feb 01 2014