public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* problem with dlsym to fetch address of some functions
@ 2014-09-23 19:37 Paulo César Pereira de Andrade
  2014-09-23 19:53 ` Marco Atzeri
  0 siblings, 1 reply; 4+ messages in thread
From: Paulo César Pereira de Andrade @ 2014-09-23 19:37 UTC (permalink / raw)
  To: cygwin

  Hi,

  Forgive me if this is expected. I am probably abusing dlsym
behavior on other systems.

(gdb) p sprintf
$1 = {<text variable, no debug info>} 0x10044b300 <sprintf>
(gdb) p (void*)dlsym(NULL, "sprintf")
$2 = (void *) 0x7708a738 <sprintf>

  The test driver I use for http://www.gnu.org/software/lightning
calls dlsym in its pseudo assembler to resolve address of
functions.

  If using dlsym in the above example, it will return the address
of some function that does not handle float arguments, and
%f format will just print "f".

(gdb) x/i sprintf
   0x10044b300 <sprintf>:
    jmpq   *0x16026(%rip)        # 0x10046132c <__imp_sprintf>
(gdb) x/i 0x7708a738
   0x7708a738 <sprintf>:        mov    %rsp,%rax

  Since dlsym is only used to write test cases, at first I should
use a pseudo patch like this:

---%<---
#if __CYGWIN__
        /* FIXME kludge to pass varargs test case, otherwise,
         * will not print/scan float values */
        if (strcmp(parser.string + 1, "sprintf") == 0)
            value = sprintf;
        else if (strcmp(parser.string + 1, "sscanf") == 0)
            value = sscanf;
        else
#endif
        {
            value = dlsym(DL_HANDLE, parser.string + 1);
            if ((string = dlerror()))
                error("%s", string);
        }
---%<---

Thanks,
Paulo

--
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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: problem with dlsym to fetch address of some functions
  2014-09-23 19:37 problem with dlsym to fetch address of some functions Paulo César Pereira de Andrade
@ 2014-09-23 19:53 ` Marco Atzeri
  2014-09-23 21:27   ` Paulo César Pereira de Andrade
  0 siblings, 1 reply; 4+ messages in thread
From: Marco Atzeri @ 2014-09-23 19:53 UTC (permalink / raw)
  To: cygwin

On 23/09/2014 20:43, Paulo César Pereira de Andrade wrote:
>    Hi,
>
>    Forgive me if this is expected. I am probably abusing dlsym
> behavior on other systems.

It will be much more clear if you

1) produce a simple small complete test case,
2) explain the outcome you obtain (or not)
3) explain the result you are expecting.

I had difficulties to understand what you are asking us.

Marco

--
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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: problem with dlsym to fetch address of some functions
  2014-09-23 19:53 ` Marco Atzeri
@ 2014-09-23 21:27   ` Paulo César Pereira de Andrade
  2014-09-24  7:41     ` Peter Rosin
  0 siblings, 1 reply; 4+ messages in thread
From: Paulo César Pereira de Andrade @ 2014-09-23 21:27 UTC (permalink / raw)
  To: cygwin

2014-09-23 16:40 GMT-03:00 Marco Atzeri <marco.atzeri@gmail.com>:
> On 23/09/2014 20:43, Paulo César Pereira de Andrade wrote:
>>
>>    Hi,
>>
>>    Forgive me if this is expected. I am probably abusing dlsym
>> behavior on other systems.
>
>
> It will be much more clear if you

  Sorry for not clear initial problem description.

> 1) produce a simple small complete test case,

$ cat x.c
extern int sprintf(char*,char*, ...);
extern int puts(char*);
extern void *dlsym(void*, char*);
char buff[128];
int main(void) {
int (*fn)(char*,char*,...);
sprintf(buff, "%.1f", 1.0);
puts(buff);
fn = dlsym((void*)0, "sprintf");
(*fn)(buff, "%.1f", 1.0);
puts(buff);
return 0;
}

$ gcc -O0 -g3 x.c

> 2) explain the outcome you obtain (or not)

$ ./a.exe
1.0
f

> 3) explain the result you are expecting.

The expected result would be:

$ ./a.exe
1.0
1.0

> I had difficulties to understand what you are asking us.
>
> Marco

Thanks,
Paulo

> --
> 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

--
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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: problem with dlsym to fetch address of some functions
  2014-09-23 21:27   ` Paulo César Pereira de Andrade
@ 2014-09-24  7:41     ` Peter Rosin
  0 siblings, 0 replies; 4+ messages in thread
From: Peter Rosin @ 2014-09-24  7:41 UTC (permalink / raw)
  To: cygwin

On 2014-09-23 21:52, Paulo César Pereira de Andrade wrote:
> 2014-09-23 16:40 GMT-03:00 Marco Atzeri <marco.atzeri@gmail.com>:
>> On 23/09/2014 20:43, Paulo César Pereira de Andrade wrote:
>>>
>>>    Hi,
>>>
>>>    Forgive me if this is expected. I am probably abusing dlsym
>>> behavior on other systems.
>>
>>
>> It will be much more clear if you
> 
>   Sorry for not clear initial problem description.
> 
>> 1) produce a simple small complete test case,
> 
> $ cat x.c
> extern int sprintf(char*,char*, ...);
> extern int puts(char*);
> extern void *dlsym(void*, char*);
> char buff[128];
> int main(void) {
> int (*fn)(char*,char*,...);
> sprintf(buff, "%.1f", 1.0);
> puts(buff);
> fn = dlsym((void*)0, "sprintf");
> (*fn)(buff, "%.1f", 1.0);
> puts(buff);
> return 0;
> }
> 
> $ gcc -O0 -g3 x.c
> 
>> 2) explain the outcome you obtain (or not)
> 
> $ ./a.exe
> 1.0
> f

The problem is that sprintf is a popular function available in
many dlls. Especially so on Cygwin which is a layer upon layer
thingy. When you are not specifying what dll dlsym should look
in, dlsym just picks the first sprintf it finds.

Consider this program:

#include <stdio.h>
#include <dlfcn.h>

char buff[128];

int main(void) {
	int (*fn)(char*,char*,...);

	void *cygwin1 = dlopen("cygwin1.dll", RTLD_GLOBAL);
	void *ntdll = dlopen("ntdll.dll", RTLD_GLOBAL);
	void *msvcrt = dlopen("msvcrt.dll", RTLD_GLOBAL);

	printf("cygwin1 %p\n", cygwin1);
	printf("ntdll   %p\n", ntdll);
	printf("msvcrt  %p\n", msvcrt);

	fn = dlsym(RTLD_DEFAULT, "sprintf");
	printf("\n\"default\" sprintf %p\n", fn);
	(*fn)(buff, "%.1f", 1.0);
	puts(buff);

	fn = dlsym(cygwin1, "sprintf");
	printf("\ncygwin1 sprintf %p\n", fn);
	(*fn)(buff, "%.1f", 1.0);
	puts(buff);

	fn = dlsym(ntdll, "sprintf");
	printf("\nntdll sprintf %p\n", fn);
	(*fn)(buff, "%.1f", 1.0);
	puts(buff);

	fn = dlsym(msvcrt, "sprintf");
	printf("\nmsvcrt sprintf %p\n", fn);
	(*fn)(buff, "%.1f", 1.0);
	puts(buff);
	return 0;
}

It produces the following output for me (Cygwin/32):

cygwin1 0x61000000
ntdll   0x77970000
msvcrt  0x75c70000

"default" sprintf 0x77a45555
f

cygwin1 sprintf 0x610d7784
1.0

ntdll sprintf 0x77a45555
f

msvcrt sprintf 0x75c8d354
1.0

So, it appears that you get ntdll:sprintf, which apparently
is not a very complete version. Maybe Cygwin could do better
and look in Cygwin dlls before going on to lower level stuff?
PTC, I'm sure...

Cheers,
Peter


--
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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-09-24  7:34 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-23 19:37 problem with dlsym to fetch address of some functions Paulo César Pereira de Andrade
2014-09-23 19:53 ` Marco Atzeri
2014-09-23 21:27   ` Paulo César Pereira de Andrade
2014-09-24  7:41     ` Peter Rosin

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).