Mangle name in fpc-FreeBSD ?

classic Classic list List threaded Threaded
38 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Mangle name in fpc-FreeBSD ?

fredvs
Hello.

I have problem to access methods from a C library.

For FreeBSD, the methods cannot be accessed (but ok for Linux and Windows).

In FreeBSD, LoadLibrary(aac.so) is working but all GetProcAdress() for each method fail.

I already ask help in FreeBSD forum :  https://forums.freebsd.org/threads/55305/

But without luck.

Could it be that something is wrong with mangle-name of exported methods of the library in FreeBSD ?

Does anybody have a idea why GetProcAdress() fail in FreeBSD (but ok for Linux and Windows) ?

Or must the library-code be compiled with some special instructions for fpc ?

Every comment or light is highly welcome (tips, must-know, etc,...).

PS: A solution is highly expected because there are other libraries, with same problems in FreeBSD, that wait to be used by fpc-FreeBSD.

Many thanks.

Fre;D

Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Sven Barth-2

Am 14.03.2016 16:16 schrieb "fredvs" <[hidden email]>:
>
> Hello.
>
> I have problem to access methods from a C library.
>
> For FreeBSD, the methods cannot be accessed (but ok for Linux and Windows).
>
> In FreeBSD, LoadLibrary(aac.so) is working but all GetProcAdress() for each
> method fail.
>
> I already ask help in FreeBSD forum :
> https://forums.freebsd.org/threads/55305/
>
> But without luck.
>
> Could it be that something is wrong with mangle-name of exported methods of
> the library in FreeBSD ?

You could check with objdump or nm what the exported symbols look like in the library. There are some systems that export C functions with a leading '_' for example.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
> You could check with objdump or nm what the exported symbols look like in the library. There are some systems that export > C functions with a leading '_' for example.

Hello Sven and thanks for answer.

Here result of nm on FreeBSD 64.



But it seems that the exported functions have the same names as for Linux or Windows (like "mp4ff_open_read", "mp4ff_close", ...)

Or do you see a "special" exported name ?

Many thanks.
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Marc Santhoff-2
In reply to this post by fredvs
On Mo, 2016-03-14 at 08:15 -0700, fredvs wrote:
> Hello.
>
> I have problem to access methods from a C library.
>
> For FreeBSD, the methods cannot be accessed (but ok for Linux and Windows).
>
> In FreeBSD, LoadLibrary(aac.so) is working but all GetProcAdress() for each
> method fail.

> Does anybody have a idea why GetProcAdress() fail in FreeBSD (but ok for
> Linux and Windows) ?
>
> Or must the library-code be compiled with some special instructions for fpc
> ?
>
> Every comment or light is highly welcome (tips, must-know, etc,...).

It would be helpful to see the code fragments in question. The
declaration of the external functions if any and the code calling
LoadLibrary() and GetProcAddress().

--
Marc Santhoff <[hidden email]>

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
> it would be helpful to see the code fragments in question.
> The declaration of the external functions if any and the code calling
> LoadLibrary() and GetProcAddress().

Hello Mark and thanks for help.

Here declaration to load-getprocess:
-----------------------------------------------------
var
  mp4ff_open_read    : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl;
  libpointer : {$IFDEF MSWINDOWS}longword{$ELSE}{$IFDEF CPU32}longword{$ELSE}PtrInt{$ENDIF}{$ENDIF};
...

libpointer := DynLibs.SafeLoadLibrary(PChar(mp4ff)); -> OK for FreeBSD64 too;-)

 Pointer(mp4ff_open_read) :=
        GetProcAddress(hMp4ff, pchar('mp4ff_open_read')); -> Here always = nil for FreeBSD 64 ;-( (but ok for Linux + Windows)
...
-----

Thanks.

Fre;D

PS: I have the same problem for other libraries in FreeBSD 64 -> GetProcAddress() fail.
PS2: It appends for some libraries in FreeBSD64, not all.
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Marc Santhoff-2
On Do, 2016-03-17 at 04:27 -0700, fredvs wrote:

> > it would be helpful to see the code fragments in question.
> > The declaration of the external functions if any and the code calling
> > LoadLibrary() and GetProcAddress().
>
> Hello Mark and thanks for help.
>
> Here declaration to load-getprocess:
> -----------------------------------------------------
> var
>   mp4ff_open_read    : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl;
>   libpointer : {$IFDEF MSWINDOWS}longword{$ELSE}{$IFDEF
> CPU32}longword{$ELSE}PtrInt{$ENDIF}{$ENDIF};
> ...
>
> libpointer := DynLibs.SafeLoadLibrary(PChar(mp4ff)); -> OK for FreeBSD64
> too;-)
>
>  Pointer(mp4ff_open_read) :=
>         GetProcAddress(hMp4ff, pchar('mp4ff_open_read')); -> Here always =
> nil for FreeBSD 64 ;-( (but ok for Linux + Windows)
> ...
> -----

When following the procedure calls I find:

<dynlibs.pas>
Function GetProcAddress(Lib : TlibHandle; const ProcName : AnsiString) :
Pointer;

begin
  Result:=GetProcedureAddress(Lib,Procname);
end;
</dynlibs.pas>

Next is:

<dynlibs.inc>
Function GetProcedureAddress(Lib : TLibHandle; const ProcName :
AnsiString) : Pointer;

begin
  Result:=dlsym(lib,pchar(ProcName));
end;
</dynlibs.inc>

Okay, man page says:

http://www.freebsd.org/cgi/man.cgi?query=dlsym&apropos=0&sektion=0&manpath=FreeBSD+10.2-RELEASE&arch=default&format=html

You could do some things, like trying to use the special handle
RTLD_NEXT, or and much more important, call dlerror() after the failing
dlsym(). It should tell _why_ the call failed.

> PS: I have the same problem for other libraries in FreeBSD 64 ->
> GetProcAddress() fail.
> PS2: It appends for some libraries in FreeBSD64, not all.

Intresting. I know there are differences in the systems dlopen() and
another similar variant installed by libtool, found in libbtdl regarding
to my notes. Dunno if it matters. Libtools implementation does
differentiate between OSs by itself (at compile time). Cold be a source
of confusion...

--
Marc Santhoff <[hidden email]>

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
> When following the procedure calls I find:
...

Hello Mark.

Thanks for your light.

Huh, yes, IMO, there is something strange in dlsym/FreeBSD.

And asking something about C library/compiler is extremely sensible there on FreeBSD forum.
(FreeBSD needs 8 (!) different C compilers (clang, c++, CC, cc, cpp, ...) to compile himself).

OK, the solution is to wait for a solution.

Many thanks.

Fre;D
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Marc Santhoff-2
On Fr, 2016-03-18 at 16:34 -0700, fredvs wrote:
> > When following the procedure calls I find:
> ...
>
> Hello Mark.
>
> Thanks for your light.
>
> Huh, yes, IMO, there is something strange in dlsym/FreeBSD.

Would you mind telling the result of dlerror()?

> And asking something about C library/compiler is extremely sensible there on
> FreeBSD forum.
> (FreeBSD needs 8 (!) different C compilers (clang, c++, CC, cc, cpp, ...) to
> compile himself).

Not really. Since c++ is the same compiler as (g)cc, cpp is the C
ppreprocessor an CC is mostly only used as a variable name in Makefiles
and shell skripts set to the right compiler, that is clearly wrong.

There are in fact different C compilers which are all able to compile C
or C++. There is actually the system compiler, which has been gcc and
will be or is already clang. Some ports require newer versions of gcc,
so sometimes there are two or three of them installed. But that's it,
AFAIK.

Look:

marc@puma:/home/marc > cc -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]

marc@puma:/home/marc > gcc -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]

marc@puma:/home/marc > CC -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]

marc@puma:/home/marc > c++ -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]

marc@puma:/home/marc > cpp --version
cpp (GCC) 4.2.1 20070831 patched [FreeBSD]
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

All the same. ;)
Only that one differs:

marc@puma:/home/marc > clang -v
FreeBSD clang version 3.0 (tags/RELEASE_30/final 145349) 20111210
Target: x86_64-unknown-freebsd9.0
Thread model: posix


You can try looking at the manual pages, type in "man cc" and the other
names.

--
Marc Santhoff <[hidden email]>

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
> Would you mind telling the result of dlerror()?

OK, I will follow your tips.
Write you later with the result.

> There are in fact different C compilers which are all able to compile C
or C++.

Yes and nearly all that compilers are the same (why not use sym-link?)

-> "Why not use sym-link in place of copy 8x the same compiler (+- 8 megas) with different name " -> Dont ask this to FreeBSD forum -> It is sensible. (I already try)

-> "Why, in the script to create-compile the kernel of FreeBSD, different compilers are used (that are the same in fact).
Would it not be simpler to use only one compiler ? "  -> Dont ask this to FreeBSD forum -> It is sensible.  (I already try)

PS: I will become totally fan of FreeBSD when the C-war will end and when it will be easy to recompile the kernel (with only one compiler).

Many thanks for your excellent tips Marc.

Write you later.

Fre;D

Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
Hello Marc.

Huh, I have a dummy question...

How do you use dlopen(), dlsym() and dlerror() ?

On console, with ->

fred@freebsd> dlopen('/root/mylib.so')

Result = "Illegal command name..."

> call dlerror() after the failing dlsym(). It should tell _why_ the call failed.

Re-huh..., it should be a great plus if a dlerror() was implemented in fpc too.

But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can be done by pascal code (and not via console, like I try).

Thanks.

Fre;D
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Ewald-2
On 03/19/2016 07:49 PM, fredvs wrote:

> Hello Marc.
>
> Huh, I have a dummy question...
>
> How do you use dlopen(), dlsym() and dlerror() ?
>
> On console, with ->
>
> fred@freebsd> dlopen('/root/mylib.so')
>
> Result = "Illegal command name..."
>
>> call dlerror() after the failing dlsym(). It should tell _why_ the call
>> failed.
> Re-huh..., it should be a great plus if a dlerror() was implemented in fpc
> too.
>
> But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can
> be done by pascal code (and not via console, like I try).
>
dlopen, dlsym and dlerror are *functions*, not console commands. Well, I
never tried the latter, but it appears they are not on your system ;-)

Now, I don't know where exactly these functions are declared (in which
unit, that is), but for debugging purposes, just add

    Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external;
    Function dlclose(handle: Pointer): cint; cdecl; external;
    Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external;
    Function dlerror: PChar; cdecl; external;

Somewhere in your code before you call them.

--
Ewald

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I
> never tried the latter, but it appears they are not on your system ;-)

> Now, I don't know where exactly these functions are declared (in which
> unit, that is), but for debugging purposes, just add

>    Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external;
>    Function dlclose(handle: Pointer): cint; cdecl; external;
>    Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external;
>    Function dlerror: PChar; cdecl; external;

> Somewhere in your code before you call them.

Ooops, thanks for answer but now I am completely loosed... ;-(

So  those functions can be used in fpc code?
If so, must a library be loaded to access that functions (and what library)?
Or are those functions defined in a fpc unit ?

I am in the dark.

Fre;D


Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Marco van de Voort
In reply to this post by Ewald-2
In our previous episode, Ewald said:

> > Re-huh..., it should be a great plus if a dlerror() was implemented in fpc
> > too.
> >
> > But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can
> > be done by pascal code (and not via console, like I try).
> >
> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I
> never tried the latter, but it appears they are not on your system ;-)
>
> Now, I don't know where exactly these functions are declared (in which
> unit, that is), but for debugging purposes, just add
>
>     Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external;
>     Function dlclose(handle: Pointer): cint; cdecl; external;
>     Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external;
>     Function dlerror: PChar; cdecl; external;
>
> Somewhere in your code before you call them.

... or use unit dl.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Ewald-2
On 03/19/2016 08:53 PM, Marco van de Voort wrote:

> In our previous episode, Ewald said:
>>> Re-huh..., it should be a great plus if a dlerror() was implemented in fpc
>>> too.
>>>
>>> But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can
>>> be done by pascal code (and not via console, like I try).
>>>
>> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I
>> never tried the latter, but it appears they are not on your system ;-)
>>
>> Now, I don't know where exactly these functions are declared (in which
>> unit, that is), but for debugging purposes, just add
>>
>>     Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external;
>>     Function dlclose(handle: Pointer): cint; cdecl; external;
>>     Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external;
>>     Function dlerror: PChar; cdecl; external;
>>
>> Somewhere in your code before you call them.
> ... or use unit dl.

I knew they were in some unit somewhere ;-) Thanks for the pointer!

--

Ewald

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Ewald-2
In reply to this post by fredvs
On 03/19/2016 08:29 PM, fredvs wrote:

>> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I
>> never tried the latter, but it appears they are not on your system ;-)
>> Now, I don't know where exactly these functions are declared (in which
>> unit, that is), but for debugging purposes, just add
>>    Function dlopen(filename: PChar; flags: cint): Pointer; cdecl;
>> external;
>>    Function dlclose(handle: Pointer): cint; cdecl; external;
>>    Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external;
>>    Function dlerror: PChar; cdecl; external;
>> Somewhere in your code before you call them.
> Ooops, thanks for answer but now I am completely loosed... ;-(
>
> So  those functions can be used in fpc code?
> If so, must a library be loaded to access that functions (and what library)?
> Or are those functions defined in a fpc unit ?

See Marco's answer. So instead of using the above declarations, a simple
`Uses dl;` should do the trick.

As to how to use them, now you do something like this:
    X:= GetProcedureAddress(...);
    Y:= GetProcedureAddress(...);
    Z:= GetProcedureAddress(...);

When one of these fails, a nil pointer is returned. dlerror will give
you more info on what failed where. So, if you know X returns nil for
some-yet-to-be-determined-reason, place the dlerror immediately after that:
    X:= GetProcedureAddress(...);
    WriteLn(dlerror);
    Y:= GetProcedureAddress(...);
    Z:= GetProcedureAddress(...);

Of course, you could choose to do something like this if you do not know
which call exactly fails:
    X:= GetProcedureAddress(...);
    If X = nil Then
        WriteLn('Z: ', dlerror);
    Y:= GetProcedureAddress(...);
    If Y = nil Then
        WriteLn('Y: ', dlerror);
    Z:= GetProcedureAddress(...);
    If Z = nil Then
        WriteLn('Z: ', dlerror);

It is really nothing more than a function call, quite similar to fpGetErrNo.


> I am in the dark.

Being in the dark is positive, as one can always turn on the lights :-)

--
Ewald


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
@ Marco and Marc thanks for help.

Sorry I do not have easy internet connection so I worked by my side.

I will try your tips.

By the way, here are my investigations:

____________________________________

Hello.

Ok, ok, understood and wow.

Added in code:

    Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external;
    Function dlclose(handle: Pointer): cint; cdecl; external;
    Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external;
    Function dlerror: PChar; cdecl; external;

and, magic, it works. ;-)

Now the result:

In code:

procedure loadmylib(lib : pchar);
var
ap1, ap2, ap3 : pointer;
'
begin
/// FreeBSD functions:
ap1 := dlopen(Pchar(lib), 0);
if ap1 <> nil then
writeln('dlopen() is OK') else
writeln('dlopen() is NOT OK') ;

ap2 := dlsym(ap1, Pchar('mp4ff_open_read');
if ap2 <> nil then
writeln('dlsym() is OK') else
writeln('dlsym() is NOT OK') ;

writeln(dlerror());

end;

---> result:
writeln('dlopen() is OK')
writeln('dlsym() is OK')
_ (no error)

--------------------------------------
Now with DynLibs:

procedure loadmylib(lib : pchar);
var
ap1: pointer;
hn : integer;
'
begin
/// with dynlibs
hn := dynlibs.loadlibrary(Pchar(lib));

if hn <> 0 then
writeln('loadlibrary() is OK') else
writeln('loadlibrary() is NOT OK') ;

ap1 := getprocedureaddress(hn, Pchar('mp4ff_open_read');

if ap1 <> nil then
writeln('getprocedureaddress() is OK') else
writeln('getprocedureaddress() is NOT OK') ;

end;

--> result:

loadlibrary() is OK
getprocedureaddress() is NOT OK

............
 
Conclusion: Maybe getprocedureaddress() has problems.

PS: Other tips are welcome.

Fre;D














Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
OOOps, in previos mail:
Thanks to Ewald, Marco and Marc.

Fre;D
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
In reply to this post by fredvs
Just quick before they cut the signal...

Could dlsym(ap1, Pchar('mp4ff_open_read') be used in place of getprocedureaddress(hn, Pchar('mp4ff_open_read')  ?

Because, if dlsym() works, maybe replacing all getprocedureaddress() with dlsym() will work?

And can loadlibrary() be used by dlsym()  ( or dlsym() needs dlopen() ) ?

Thanks.

Fre;D
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

fredvs
Re-hello (and last for tonight).

Yep, yep, yep.

Replacing all GetProcedureAdress() with dlsym()

DOES THE TRICK ! ;-)

(but dlopen() is needed in place of Loadlibrary())

Excellent tip.

Many, many, many thanks for help.

(And, maybe, a check for DynLibs.GetProcedureAdress() is needed for FreeBSD).

And re-thanks for your bright light.

PS: This is a great victory who will solve (I hope) other library-related problems.
PS2: Are there limitations of using dlsym() vs GetProcedureAdress() ?
PS3: If dlsym() is cross-platform too, should I update all my codes that use GetProcedureAdress() ?

Fre;D
Many thanks ;-)
Reply | Threaded
Open this post in threaded view
|

Re: Mangle name in fpc-FreeBSD ?

Sven Barth-2

Am 20.03.2016 00:57 schrieb "fredvs" <[hidden email]>:
> PS: This is a great victory who will solve (I hope) other library-related
> problems.
> PS2: Are there limitations of using dlsym() vs GetProcedureAdress() ?
> PS3: If dlsym() is cross-platform too, should I update all my codes that use
> GetProcedureAdress() ?

LoadLibrary and GetProcedureAddress internally use dlopen and dlsym respectively on Unix-like platforms. So it might be that either LoadLibrary or GetProcedureAddress calls its respective internal function incorrectly on FreeBSD and that needs to be fixed then.
And no, dlopen and dlsym are not cross platform (e.g. not on Windows) that's.why the LoadLibrary and GetProcedureAddress functions exist in the first place.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
12