* problem building a dll that uses other dll's
@ 1997-08-22 12:21 Dan Goldwater
0 siblings, 0 replies; 3+ messages in thread
From: Dan Goldwater @ 1997-08-22 12:21 UTC (permalink / raw)
To: gnu-win32
Hi!
I am trying to build a DLL which has function calls which must be
resolved into existing win32 DLL's.
I am using b18 on winNT 4.0. i have MSVC 5.0 available.
Following the instructions for building a relocatable dll, i get an
output but each of the three ld steps reports all the undefined
references for the functions which are in the existing win32 dll's. i had
to add the --noinhibit-exec option to ld so that it wouldn't delete the
output dll due to the errors. if i try to use the result dll, it says it
is an invalid image...
when i build this project on solaris, the linker doesn't complain about the
undefined references, and they are resolved to appropriate existing .so
files at runtime.
is there some option i need to give ld so it knows i want to resolve the
references at runtime to the existing dll's? or am i clueless?
thanks!
---------------------------------------------------------
Dan Goldwater dgold@brown.edu
http://fatmac.ee.cornell.edu/~goldwada
---------------------------------------------------------
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: problem building a dll that uses other dll's
[not found] ` <199708251852.OAA02984@nut.brown.edu>
@ 1997-08-25 23:11 ` Mikey
0 siblings, 0 replies; 3+ messages in thread
From: Mikey @ 1997-08-25 23:11 UTC (permalink / raw)
To: dgold, gnu-win32
[-- Attachment #1: Type: text/plain, Size: 1531 bytes --]
These are from the SDK_4_ming_cygwin32
lib2def does the obvious, the Makefile
should show you how to use it.
If you don't have the .lib file, you can use impdef.exe
to generate the .def file, you may need to edit it
to eliminate c++ junk, (vc++ has different
name mangling conventions then g++)
just redirect the output of impdef to a file, then
run dlltool on it as shown in the enclosed Makefile.
On Mon, 25 Aug 1997 14:54:39 -500, you wrote:
>> The dll is not the stub library, the stub library
>> for foo.dll is libfoo.a
>
>ok, the thing is that i don't have the stub library for foo.dll. foo.dll
>is from a commercial product. does this mean i'm stuck? if i had the .a
>files i would have been all set long ago :)
>
>is there some way to generate the .a file for foo.dll?
>
>> BTW all of this stuff is in the ld man page, and also
>> in gcc.info, you might try reading them.
>
>really i already knew all the basics of ld, the stuff i'm having the
>problem with is specific to gnuwin32.
Then why are you asking about -l "small L"?
One of the basics of ld, is that you don't link directly with coff or aout
shared libraries, you have to make a stub library first.
That's the main reason why linux when to ELF.
>
>thanks.
>---------------------------------------------------------
>Dan Goldwater dgold@brown.edu
> http://fatmac.ee.cornell.edu/~goldwada
>---------------------------------------------------------
>
>
>
(jeffdbREMOVETHIS@netzone.com)
delete REMOVETHIS from the above to reply
Mikey
[-- Attachment #2: impdef.c --]
[-- Type: text/x-c, Size: 10780 bytes --]
//==================================
// This is a modification of:
// PEDUMP - Matt Pietrek 1995
// done by Ismael Jurado 1997
//
// This program only outputs to stdout a DEF file from a DLL given in the
// command line.
// I don´t know how to contact Matt, so if this program is not legal, please
// let me know.
// ismaelj@hotmail.com
//==================================
#include <windows.h>
#include <stdio.h>
int flag2 = 1;
// This code was taken from WINNT.H, which is not included in the current
// Cygnus port.
#ifndef _WINNT_
#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
((DWORD)ntheader + \
FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
))
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Reserved1;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
PDWORD *AddressOfFunctions;
PDWORD *AddressOfNames;
PWORD *AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
#endif // __WINNT__
// Here starts Matt's code
//
//
// MakePtr is a macro that allows you to easily add to values (including
// pointers) together without dealing with C's pointer arithmetic. It
// essentially treats the last two parameters as DWORDs. The first
// parameter is used to typecast the result to the appropriate pointer type.
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue))
PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva,
PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
unsigned i;
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ ) {
// Is the RVA within this section?
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + section->Misc.VirtualSize)))
return section;
}
return 0;
}
void DumpExportsSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader) {
PIMAGE_EXPORT_DIRECTORY exportDir;
PIMAGE_SECTION_HEADER header;
INT delta;
DWORD i;
PDWORD functions;
PWORD ordinals;
PSTR *name;
DWORD exportsStartRVA, exportsEndRVA;
exportsStartRVA = pNTHeader->OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
exportsEndRVA = exportsStartRVA + pNTHeader->OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
// Get the IMAGE_SECTION_HEADER that contains the exports. This is
// usually the .edata section, but doesn't have to be.
header = (PIMAGE_SECTION_HEADER)GetEnclosingSectionHeader( exportsStartRVA, pNTHeader );
if ( !header ) return;
delta = (INT)(header->VirtualAddress - header->PointerToRawData);
exportDir = MakePtr(PIMAGE_EXPORT_DIRECTORY, base, exportsStartRVA - delta);
if (flag2)
printf("EXPORTS\n");
functions = (PDWORD)((DWORD)exportDir->AddressOfFunctions - delta + base);
ordinals = (PWORD)((DWORD)exportDir->AddressOfNameOrdinals - delta + base);
name = (PSTR *)((DWORD)exportDir->AddressOfNames - delta + base);
for ( i=0; i < exportDir->NumberOfFunctions; i++ ) {
DWORD entryPointRVA = functions[i];
DWORD j;
int flag=0;
if ( entryPointRVA == 0 ) // Skip over gaps in exported function
continue; // ordinals (the entrypoint is 0 for
// these functions).
// See if this function has an associated name exported for it.
for ( j=0; j < exportDir->NumberOfNames; j++ )
if ( ordinals[j] == i ) {
printf("%s", name[j] - delta + base);
if (flag2)
printf("\t@%u", i + exportDir->Base);
flag=1;
}
// Is it a forwarder? If so, the entry point RVA is inside the
// .edata section, and is an RVA to the DllName.EntryPointName
if ( (entryPointRVA >= exportsStartRVA)&&(entryPointRVA <= exportsEndRVA) )
{
printf("%s", entryPointRVA - delta + base);
if (flag2)
printf("\t@%u", i + exportDir->Base);
flag=1;
}
if (flag) printf("\n");
}
}
void DumpExeFile( PIMAGE_DOS_HEADER dosHeader )
{
PIMAGE_NT_HEADERS pNTHeader;
DWORD base = (DWORD)dosHeader;
pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader,
dosHeader->e_lfanew );
// First, verify that the e_lfanew field gave us a reasonable
// pointer, then verify the PE signature.
// IJ: gcc doesn't support C exeptions??
// __try
// {
if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
{
printf("Not a Portable Executable (PE) EXE\n");
return;
}
// }
/*
__except( TRUE ) // Should only get here if pNTHeader (above) is bogus
{
printf( "invalid .EXE\n");
return;
}
*/
DumpExportsSection(base, pNTHeader);
printf("\n");
}
void DumpFile(LPSTR filename)
{
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("Couldn't open file with CreateFile()\n");
return;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( hFileMapping == 0 )
{
CloseHandle(hFile);
printf("Couldn't open file mapping with CreateFileMapping()\n");
return;
}
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if ( lpFileBase == 0 )
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
printf("Couldn't map view of file with MapViewOfFile()\n");
return;
}
if (flag2)
printf(";Exports of file %s\n\n", filename);
dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
if ( dosHeader->e_magic == IMAGE_DOS_SIGNATURE )
{
DumpExeFile( dosHeader );
}
else printf("Format Unknown!\n");
}
char HelpText[] =
"IMPDEF\n"
"Syntax: IMPDEF DLLname\n\n"
"Modification of:\n"
"PEDUMP - Win32/COFF EXE/OBJ/LIB file dumper - 1995 Matt Pietrek\n"
"by Ismael Jurado 1997. Only produces a DEF file from a DLL\n"
"Let me know if this modification is not legal: ismaelj@hotmail.com\n";
int main(int argc, char *argv[]) {
if ( argc == 1 ) {
printf( HelpText );
return 1;
}
if (argc == 3 && *argv[1] == '-')
{
flag2 = 0;
DumpFile(argv[2]);
}
else
{
DumpFile(argv[1]);
}
return 0;
}
[-- Attachment #3: lib2def --]
[-- Type: text/x-shellscript, Size: 519 bytes --]
#!/bin/sh
tlow(){
echo $1|tr A-Z a-z
}
if [ x"$1" = x"" ];then
echo "shell script to generate .def files from .LIB files
$0 filename ..."
exit 0
else
echo LIBRARY `basename $1 .lib`
echo EXPORTS
echo fakefunc$RANDOM
nm --extern-only $1|egrep '^........ [TR]' \
|fgrep -v '$AA'\
|fgrep -v 'C@_0'\
|fgrep -v '@@' \
|sort \
|sed -e 's/[^_]*_//' -e 's/[^?]*?//'
fi
# T= .text section R= readonly .data section (exported variables)
# $AA C@_0 @@ exported structure/internal function definitions
[-- Attachment #4: Makefile --]
[-- Type: text/x-makefile, Size: 2961 bytes --]
.PHONY: all install clean distclean uninstall distuninstall
#these are here to be overidden from the command line or the top level Makefile
prefix = `gcc -print-file-name=crt0.o|sed -e s/\\\\\\\\/\\\\//g -e s/\\\\/i386-cygwin32\\\\/lib\\\\/crt0.o//`
exec_prefix := $(shell echo ${prefix})
SDK=/m/mstools
SDKD = ${SDK}
ifeq "$(findstring i386-cygwin32,$(exec_prefix))" "i386-cygwin32"
INSTALLDIR=$(exec_prefix)/i386-cygwin32/lib
else
INSTALLDIR=$(exec_prefix)/lib
endif
.SUFFIXES: $(SUFFIXES) .lib .LIB .def .dll .a
OURLIBS= libcrtdll.a liblargeint.a liboldnames.a
BASELIBS= \
libadvapi32.a \
libcomctl32.a \
libcomdlg32.a \
libgdi32.a \
libimm32.a \
libkernel32.a \
liblsapi32.a \
libmswsock.a \
libnetapi32.a \
libole32.a \
liboleaut32.a \
librasapi32.a \
libshell32.a \
libuser32.a \
libuuid.a \
libversion.a \
libwinmm.a \
libwinspool.a \
libws2_32.a \
libwsock32.a \
CYGLIBS= \
libcap.a \
libctl3d32.a \
libdlcapi.a \
libglu32.a \
libicmp.a \
liblargeint.a \
liblz32.a \
libmapi32.a \
libmfcuia32.a \
libmgmtapi.a \
libmpr.a \
libmsacm32.a \
libnddeapi.a \
libodbc32.a \
libodbccp32.a \
liboledlg.a \
libolepro32.a \
libopengl32.a \
libpenwin32.a \
libpkpd32.a \
librpcdce4.a \
librpcndr.a \
librpcns4.a \
librpcrt4.a \
libscrnsave.a \
libsnmp.a \
libsvrapi.a \
libtapi32.a \
libth32.a \
libthunk32.a \
liburl.a \
libvdmdbg.a \
libvfw32.a \
libwin32spl.a \
libwinserve.a \
libwinstrm.a \
libwow32.a \
libwst.a \
SDKLIBS=$(addprefix lib,$(addsuffix .a,$(basename $(notdir $(wildcard $(SDK)/lib/*.lib)))))
all: $(OURLIBS) $(BASELIBS)
install-mylib:
install *.a $(INSTALLDIR)/
libcrtdll.a: crtdll.def
dlltool --dllname crtdll.dll --def $< --output-lib $@ -k
liblargeint.a: largeint.def
dlltool --dllname crtdll.dll --def $< --output-lib $@ -k
liboldnames.a: oldnames.def
dlltool --dllname crtdll.dll --def $< --output-lib $@ -k
%.def: $(SDK)/lib/%.lib
set -xv;\
[ -d obj/i386/ ] || mkdir -p obj/i386/;\
cp $< . ;\
Objs=`ar -t $(notdir $<)|grep -v \\.dll`;\
[ -z "$$Objs" ] && exit 0;\
ar -x $(notdir $<) $$Objs;\
ar -d $(notdir $<) $$Objs;\
for file in $$Objs;do \
objcopy $$file `basename $$file .obj`.o;\
rm $$file;\
done
../bin/lib2def $(notdir $<) > $@
rm $(notdir $<)
lib%.a: %.def
dlltool --dllname $*.dll --def $< --output-lib $@ -k
set -xv;\
Objs=`echo *.o`;\
[ "$$Objs" = "*.o" ] && exit 0;\
ar urvs $@ $$Objs;\
rm *.o
# to keep a copy of the .def files uncomment the next 6 lines
#%.def: $(SDK)/lib/%.lib
# -mkdir -p defs
# ../bin/lib2def $< > defs/$@
#
#lib%.a: %.def
# dlltool --dllname $*.dll --def defs/$< --output-lib $@ -k
all-SDK: $(SDKLIBS)
install: all
install -d $(INSTALLDIR)
install *.a $(INSTALLDIR)/
distclean clean:
rm -f *.a defs/*.def
distuninstall:
for file in $(OURLIBS) $(CYGLIBS) $(SDKLIBS) ;do \
rm -f $(INSTALLDIR)/$$file; \
done
-rmdir -p $(INSTALLDIR)
uninstall:
rm -f $(INSTALLDIR)/libcrtdll.a
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: problem building a dll that uses other dll's
[not found] <199708251740.NAA14070@nut.brown.edu>
@ 1997-08-25 23:11 ` Mikey
[not found] ` <199708251852.OAA02984@nut.brown.edu>
1 sibling, 0 replies; 3+ messages in thread
From: Mikey @ 1997-08-25 23:11 UTC (permalink / raw)
To: dgold, gnu-win32
The dll is not the stub library, the stub library
for foo.dll is libfoo.a
to use ld.exe directly, you would need to do
ld --subsystem [ windows/console ] --dll -e _dll_entry@12 -o prog.exe prog.o -L/search/dir -lfoo
the -l automatically adds the lib prefix, and the .a suffix. to the stub library name
-L is used to add a search path for ld.
The order of files on the link line IS important, since ld is
a one pass linker, references must be resolved by
object files farther allong in the link line.
BTW all of this stuff is in the ld man page, and also
in gcc.info, you might try reading them.
On Mon, 25 Aug 1997 13:42:04 -500, you wrote:
>> You must tell ld (or link.exe) which libraries to
>> link with.
>
>hmm.. what option are you using to do this? i tried "-l foo.dll" but it
>doesn't seem to work:
>
>gnuwin32/H-i386-cygwin32/i386-cygwin32/bin/ld.exe: cannot open
>-lhttpdlw.dll: No such file or directory
>
>maybe i just need a different syntax? but i think it is expecting a .a
>library. do you know how to do this?
>
>> easeist way is to let gcc do it.
>>
>> to link do
>>
>> gcc -Wl,--dll,-e,_dll_entry@12 -o prog.exe prog.o
>>
>> the libraries will automatically be linked in.
>
>i tried this, but without specifying the libraries (since i couldn't
>figure out the syntax for that), and it did the same thing as before -
>"undefined reference ...".
>
>thanks!
>
>> >I am trying to build a DLL which has function calls which must be
>> >resolved into existing win32 DLL's.
>> >
>> >I am using b18 on winNT 4.0. i have MSVC 5.0 available.
>> >
>> >Following the instructions for building a relocatable dll, i get an
>> >output but each of the three ld steps reports all the undefined
>> >references for the functions which are in the existing win32 dll's. i had
>> >to add the --noinhibit-exec option to ld so that it wouldn't delete the
>> >output dll due to the errors. if i try to use the result dll, it says it
>> >is an invalid image...
>
>---------------------------------------------------------
>Dan Goldwater dgold@brown.edu
> http://fatmac.ee.cornell.edu/~goldwada
>---------------------------------------------------------
>
>
>
(jeffdbREMOVETHIS@netzone.com)
delete REMOVETHIS from the above to reply
Mikey
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~1997-08-25 23:11 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-08-22 12:21 problem building a dll that uses other dll's Dan Goldwater
[not found] <199708251740.NAA14070@nut.brown.edu>
1997-08-25 23:11 ` Mikey
[not found] ` <199708251852.OAA02984@nut.brown.edu>
1997-08-25 23:11 ` Mikey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).