Symbols exported/not exported

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

Symbols exported/not exported

Elio Blanca
Hello, I am currently building in windows an application made up of a main program and a bunch of
plugins, loaded at startup.

The plugins are loaded (both in linux and in windows) via dlopen+dlsym, with the latter searching
into the plugin for a known entry point, that is a function with name ending with "_load".

Now, as an example, I do:

$ gcc -O2 -c -o waveout.o waveout.c



and I see the binary has the needed entry point:

$ nm waveout.o |grep _load

00000cf0 T _waveout_load



Now, I build the dll:

$ gcc -shared -o waveout.dll waveout.o /mingw/lib/libwinmm.a -Wl,-no-undefined
-Wl,--enable-runtime-pseudo-reloc



and again I check for the needed entry point:

$ nm waveout.dll |grep _load

00000000 A __loader_flags__

70d01fb0 T _waveout_load



Truth is, the main program will search for function "waveout_load" (no leading underscore) but
anyway the dll works, and I know I can save a bunch of bytes via stripping:

$ gcc -s -shared -o waveout.dll waveout.o /mingw/lib/libwinmm.a -Wl,-no-undefined
-Wl,--enable-runtime-pseudo-reloc



$ nm waveout.dll |grep _load

c:\MSYS_1\bin\nm.exe: waveout.dll: no symbols



Ok, no symbols found but the main application still finds the entry point and everything works.





Now, I have troubles with a different plugin. I compile it with:

$ gcc -O2 -c -o vfs_zip.o vfs_zip.c -I/usr/local/include -I/usr/local/lib/libzip/include



$ nm vfs_zip.o |grep _load

000007f0 T _vfs_zip_load



Ok, the object file has the entry point.

Build the dll:



$ gcc -s -shared -o vfs_zip.dll vfs_zip.o /usr/local/lib/libzip.a /usr/local/lib/libz.a
-Wl,-no-undefined -Wl,--enable-runtime-pseudo-reloc



$ nm vfs_zip.dll |grep _load

c:\MSYS_1\bin\nm.exe: vfs_zip.dll: no symbols



Here nm sees no symbols but I know the whole thing should work anyway.

Instead, when the main application calls dlsym, it cannot find the function "vfs_zip_load" and
cannot load the plugin.

Maybe the stripping is too aggressive?



$ gcc -shared -o vfs_zip.dll vfs_zip.o /usr/local/lib/libzip.a /usr/local/lib/libz.a
-Wl,-no-undefined -Wl,--enable-runtime-pseudo-reloc



$ nm vfs_zip.dll |grep _load

00000000 A __loader_flags__

706c1ab0 T _vfs_zip_load



Now I see the needed entry point. As stated above, it has a leading underscore but I expect it to be
found anyway.

This doesn't happen, and I don't know why, but I do those same steps for a dozen plugins and each of
them works, this last one doesn't behave the same.

I think there is some tiny subtle thing I am currently missing.

Can anybody help with this?
Elio


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe
Reply | Threaded
Open this post in threaded view
|

Re: Symbols exported/not exported

Elio Blanca



Il 25/01/2017 18:28, Elio Blanca ha scritto:
 > Hello, I am currently building in windows an application made up of a main program and a bunch of
 > plugins, loaded at startup.
 >
....
 >
 > I think there is some tiny subtle thing I am currently missing.
 >


Well, I managed to get the plugin working, though I can't surely say which trick fixed the build (or
just the linking step).
I found some useful code on the page:
http://stackoverflow.com/questions/437432/is-there-a-way-to-find-all-the-functions-exposed-by-a-dll
(the dll symbol enumerator)
and with some trick, it compiled under windows too.
At my run it listed the exposed functions from my dll:

zip_archive_set_tempdir
zip_close
zip_discard
zip_error_code_system
zip_error_code_zip
zip_error_fini
zip_error_init
zip_error_init_with_code
zip_error_set
zip_error_system_type
zip_error_to_data
zip_fclose
zip_fopen_index
zip_fopen_index_encrypted
zip_fread
zip_get_name
zip_get_num_files
zip_name_locate
zip_open
zip_open_from_source
zip_register_progress_callback
zip_source_begin_write
zip_source_buffer
zip_source_buffer_create
zip_source_close
zip_source_commit_write
zip_source_error
zip_source_file
zip_source_file_create
zip_source_free
zip_source_function
zip_source_function_create
zip_source_keep
zip_source_make_command_bitmap
zip_source_open
zip_source_read
zip_source_rollback_write
zip_source_seek
zip_source_seek_compute_offset
zip_source_seek_write
zip_source_stat
zip_source_tell
zip_source_tell_write
zip_source_win32handle
zip_source_win32handle_create
zip_source_win32w
zip_source_win32w_create
zip_source_write
zip_stat
zip_stat_index
zip_stat_init



It doesn't list the function I was after, vfs_zip_load, although 'nm' can see it. Maybe the two
programs work in different ways.
Those listed are functions exported by an included library, libzip.a
Although it seemed odd, I thought the dll had a limited amount of entry, so I wanted to remove those
unneeded ones and not expose them in order to have more room for the entries I really wanted.
Now, since those are not requested to be available into my plugin, I re-built libzip.a statically
and I removed any "__declspec(dllimport)" I could find in the function declarations. Rebuilt
libzip.a and re-built my plugin which needs libzip.a

Second run of the dll function/entry lister:
_dist_code
_length_code
_tr_align
_tr_flush_bits
_tr_flush_block
_tr_init
_tr_stored_block
_tr_tally
_zip_buffer_data
_zip_buffer_eof
_zip_buffer_free
_zip_buffer_get
_zip_buffer_get_16
_zip_buffer_get_32
_zip_buffer_get_64
_zip_buffer_get_8
_zip_buffer_left
_zip_buffer_new
_zip_buffer_new_from_source
_zip_buffer_offset
_zip_buffer_ok
_zip_buffer_peek
_zip_buffer_put
_zip_buffer_put_16
_zip_buffer_put_32
_zip_buffer_put_64
_zip_buffer_put_8
_zip_buffer_read
_zip_buffer_set_offset
_zip_buffer_size
_zip_buffer_skip
_zip_cdir_free
_zip_cdir_grow
_zip_cdir_new
_zip_cdir_write
_zip_changed
_zip_cp437_to_utf8
_zip_deregister_source
_zip_dirent_clone
_zip_dirent_finalize
_zip_dirent_free
_zip_dirent_init
_zip_dirent_needs_zip64
_zip_dirent_new
_zip_dirent_read
_zip_dirent_size
_zip_dirent_write
_zip_ef_clone
_zip_ef_delete_by_id
_zip_ef_free
_zip_ef_get_by_id
_zip_ef_merge
_zip_ef_new
_zip_ef_parse
_zip_ef_remove_internal
_zip_ef_size
_zip_ef_write
_zip_entry_finalize
_zip_entry_init
_zip_err_str
_zip_err_type
_zip_error_clear
_zip_error_copy
_zip_error_get
_zip_error_set_from_source
_zip_fcrypt_decrypt
_zip_fcrypt_encrypt
_zip_fcrypt_end
_zip_fcrypt_init
_zip_file_get_offset
_zip_get_compression_implementation
_zip_get_dirent
_zip_get_encryption_implementation
_zip_get_name
_zip_guess_encoding
_zip_hash_add
_zip_hash_delete
_zip_hash_free
_zip_hash_lookup
_zip_hash_new
_zip_hash_revert
_zip_memdup
_zip_name_locate
_zip_nerr_str
_zip_new
_zip_open
_zip_read
_zip_read_data
_zip_read_local_ef
_zip_read_string
_zip_register_source
_zip_set_open_error
_zip_source_call
_zip_source_eof
_zip_source_had_error
_zip_source_invalidate
_zip_source_new
_zip_source_set_source_archive
_zip_source_win32_handle_or_name
_zip_source_window_new
_zip_source_zip_new
_zip_stat_merge
_zip_string_crc32
_zip_string_equal
_zip_string_free
_zip_string_get
_zip_string_length
_zip_string_new
_zip_string_write
_zip_u2d_time
_zip_unchange_data
_zip_write
adler32
adler32_combine
adler32_combine64
adler32_z
crc32
crc32_combine
crc32_combine64
crc32_z
deflate
deflateBound
deflateCopy
deflateEnd
deflateGetDictionary
deflateInit2_
deflateInit_
deflateParams
deflatePending
deflatePrime
deflateReset
deflateResetKeep
deflateSetDictionary
deflateSetHeader
deflateTune
deflate_copyright
get_crc_table
inflate
inflateCodesUsed
inflateCopy
inflateEnd
inflateGetDictionary
inflateGetHeader
inflateInit2_
inflateInit_
inflateMark
inflatePrime
inflateReset
inflateReset2
inflateResetKeep
inflateSetDictionary
inflateSync
inflateSyncPoint
inflateUndermine
inflateValidate
inflate_copyright
inflate_fast
inflate_table
vfs_zip_close
vfs_zip_get_scheme_for_name
vfs_zip_get_schemes
vfs_zip_getlength
vfs_zip_is_container
vfs_zip_is_streaming
vfs_zip_load
vfs_zip_open
vfs_zip_read
vfs_zip_rewind
vfs_zip_scandir
vfs_zip_seek
vfs_zip_tell
zError
z_errmsg
zcalloc
zcfree
zip_archive_set_tempdir
zip_close
zip_discard
zip_error_code_system
zip_error_code_zip
zip_error_fini
zip_error_init
zip_error_init_with_code
zip_error_set
zip_error_system_type
zip_error_to_data
zip_fclose
zip_fopen_index
zip_fopen_index_encrypted
zip_fread
zip_get_name
zip_get_num_files
zip_name_locate
zip_open
zip_open_from_source
zip_random
zip_register_progress_callback
zip_source_begin_write
zip_source_buffer
zip_source_buffer_create
zip_source_close
zip_source_commit_write
zip_source_crc
zip_source_deflate
zip_source_error
zip_source_file
zip_source_file_create
zip_source_free
zip_source_function
zip_source_function_create
zip_source_keep
zip_source_layered
zip_source_layered_create
zip_source_make_command_bitmap
zip_source_open
zip_source_pkware
zip_source_read
zip_source_remove
zip_source_rollback_write
zip_source_seek
zip_source_seek_compute_offset
zip_source_seek_write
zip_source_stat
zip_source_supports
zip_source_tell
zip_source_tell_write
zip_source_win32handle
zip_source_win32handle_create
zip_source_win32w
zip_source_win32w_create
zip_source_window
zip_source_winzip_aes_decode
zip_source_winzip_aes_encode
zip_source_write
zip_stat
zip_stat_index
zip_stat_init
zlibCompileFlags
zlibVersion



Now the exposed functions are far more than before! They still include functions from libzip.a (so
my attempt to not expose some functions failed) and more functions from libz.a too.
But I also see the entry point I wanted, 'vfs_zip_load' and I'm now happy this way because the main
application can load the plugin.
Honestly, I cannot say why some symbols get exposed and some other don't, and I'm not sure how this
whole thing worked, but it did.
Any suggestion will be appreciated, thank you,
Elio


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe
Reply | Threaded
Open this post in threaded view
|

Re: Symbols exported/not exported

Eli Zaretskii
> From: Elio Blanca <[hidden email]>
> Date: Fri, 3 Feb 2017 23:26:23 +0100
>
>
> I found some useful code on the page:
> http://stackoverflow.com/questions/437432/is-there-a-way-to-find-all-the-functions-exposed-by-a-dll
> (the dll symbol enumerator)
> and with some trick, it compiled under windows too.

What's wrong with just using the 'pexports' utility from here:

  https://sourceforge.net/projects/mingw/files/MinGW/Extension/pexports/

which is part of MinGW?

> It doesn't list the function I was after, vfs_zip_load, although 'nm' can see it. Maybe the two
> programs work in different ways.
> Those listed are functions exported by an included library, libzip.a
> Although it seemed odd, I thought the dll had a limited amount of entry, so I wanted to remove those
> unneeded ones and not expose them in order to have more room for the entries I really wanted.
> Now, since those are not requested to be available into my plugin, I re-built libzip.a statically
> and I removed any "__declspec(dllimport)" I could find in the function declarations. Rebuilt
> libzip.a and re-built my plugin which needs libzip.a
>
> Second run of the dll function/entry lister:
[...]
> Now the exposed functions are far more than before! They still include functions from libzip.a (so
> my attempt to not expose some functions failed) and more functions from libz.a too.

This is expected, AFAIK: if the compiler/linker see no functions being
explicitly exported, they will export _all_ of them.  If that's what
you want, you've found your solution.  An alternative is to mark the
function(s) you want to be exported with '__attribute__ ((dllexport))'
(or the equivalent MS-specific '__declspec(dllexport)').  yet another
alternative is to use -Wl,--export-all-symbols switch to the link
command that produces the DLL, which will do the same as removing any
attributes from all the symbols.

> But I also see the entry point I wanted, 'vfs_zip_load' and I'm now happy this way because the main
> application can load the plugin.
> Honestly, I cannot say why some symbols get exposed and some other don't, and I'm not sure how this
> whole thing worked

See above: it depends on which of them are marked with the export
attributes.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe
Reply | Threaded
Open this post in threaded view
|

Re: Symbols exported/not exported

Elio Blanca


Il 04/02/2017 09:25, Eli Zaretskii ha scritto:
> What's wrong with just using the 'pexports' utility

Didn't know of it!
I will try using it together with the similar gendef.

Thank you for your suggestions Eli!






------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe