Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static library symbols shall be marked as hidden #354

Closed
gcode-importer opened this issue Jun 5, 2014 · 11 comments
Closed

Static library symbols shall be marked as hidden #354

gcode-importer opened this issue Jun 5, 2014 · 11 comments

Comments

@gcode-importer
Copy link

Originally reported on Google Code with ID 354

Hi,

I think that when compiling static library, symbols shall always be marked as "hidden"
(opposed to "default") so that they won't be exported from the shared object they're
linked into.

Regards,
Matthieu



Reported by mayeut on 2014-06-05 07:20:08


- _Attachment: [openjpeg-2.1.0-visibility.patch](https://storage.googleapis.com/google-code-attachments/openjpeg/issue-354/comment-0/openjpeg-2.1.0-visibility.patch)_
@gcode-importer
Copy link
Author

@Mathieu,

Any thoughts on this one so that I can fix/won't fix it ?

Reported by mayeut on 2014-12-03 20:25:22

@gcode-importer
Copy link
Author

define "compiling static library" [...] "shared object" ?

Reported by malaterre on 2014-12-04 07:52:29

@gcode-importer
Copy link
Author

If you compile OpenJPEG with -DOPJ_STATIC (that is CMAKE option BUILD_SHARED_LIBS=FALSE)
on linux, OPJ_API gets defined like this:
#define OPJ_API    __attribute__ ((visibility ("default")))

Now, if I create a libfoo.so that has been linked against the OpenJPEG static library,
symbols from the OpenJPEG API will be exported which can lead to odd behaviour if an
executable links against libfoo.so & libopenjp2.so because the executable expects symbols
from libopenjp2.so but might resolve those from libfoo.so instead (depending on loading
order & OpenJPEG version conflict)

I said "shared objects" because this is also true of executables but with some specific
options so not that relevant & confusing I guess.

Reported by mayeut on 2014-12-04 09:04:28

@gcode-importer
Copy link
Author

This seems quite right.
@Mathieu Malaterre: do you have any objection to this? Thks

Reported by detonin on 2015-01-15 18:25:22

  • Status changed: Started

@gcode-importer
Copy link
Author

Sorry to insist but:
[...]
Now, if I create a libfoo.so that has been linked against the OpenJPEG static library,
symbols from the OpenJPEG API will be exported 
[...]

does not make any sense to me. I think I am missing the whole point. Why would a symbol
from libfoo project (re)export something from libopenjp2.a ?

Reported by malaterre on 2015-01-15 19:51:19

@gcode-importer
Copy link
Author

@mathieu,

This is just how the linker works under linux/macos. Here's a small example attached
(you'll have to modify it a little in order for it to work under linux).

Here's the output under MacOS. Have a look at all 4 outputs from the test "A : x -
B : y". One would expect the output to always be "A : 0 - B : 1" but this is not the
case
 # As OpenJpeg is now (a is representing OpenJPEG)
+ gcc -fPIC -x c -O3 -c -DA_VISIBILITY_DEFAULT -DA_VERSION=0 -o a0.o a.c
+ gcc -fPIC -x c -O3 -c -DA_VISIBILITY_DEFAULT -DA_VERSION=1 -o a1.o a.c
+ gcc -fPIC -x c -O3 -c -o b.o b.c
+ gcc -fPIC -shared -o liba.dylib a0.o
+ ar rc liba.a a1.o
+ gcc -fPIC -shared -o libb.dylib b.o liba.a
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ab -Wl,liba.dylib -Wl,libb.dylib main.c
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ba -Wl,libb.dylib -Wl,liba.dylib main.c
+ ./ab
A : 0 - B : 1
+ ./ba
A : 1 - B : 1
# As OpenJpeg should be
+ gcc -fPIC -x c -O3 -c -DA_VISIBILITY_DEFAULT -DA_VERSION=0 -o a0.o a.c
+ gcc -fPIC -x c -O3 -c -DA_VERSION=1 -o a1.o a.c
+ gcc -fPIC -x c -O3 -c -o b.o b.c
+ gcc -fPIC -shared -o liba.dylib a0.o
+ ar rc liba.a a1.o
+ gcc -fPIC -shared -o libb.dylib b.o liba.a
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ab -Wl,liba.dylib -Wl,libb.dylib main.c
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ba -Wl,libb.dylib -Wl,liba.dylib main.c
+ ./ab
A : 0 - B : 1
+ ./ba
A : 0 - B : 1

Reported by mayeut on 2015-01-15 22:19:27


- _Attachment: [test.tar.gz](https://storage.googleapis.com/google-code-attachments/openjpeg/issue-354/comment-6/test.tar.gz)_

@gcode-importer
Copy link
Author

$ LD_LIBRARY_PATH=`pwd` ./test.sh 
+ gcc -fPIC -x c -O3 -c -DA_VISIBILITY_DEFAULT -DA_VERSION=0 -o a0.o a.c
+ gcc -fPIC -x c -O3 -c -DA_VISIBILITY_DEFAULT -DA_VERSION=1 -o a1.o a.c
+ gcc -fPIC -x c -O3 -c -o b.o b.c
+ gcc -fPIC -shared -o liba.dylib a0.o
+ ar rc liba.a a1.o
+ gcc -fPIC -shared -o libb.dylib b.o liba.a
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ab -Wl,liba.dylib -Wl,libb.dylib main.c
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ba -Wl,libb.dylib -Wl,liba.dylib main.c
+ ./ab
A : 0 - B : 1
+ ./ba
A : 0 - B : 1
+ gcc -fPIC -x c -O3 -c -DA_VISIBILITY_DEFAULT -DA_VERSION=0 -o a0.o a.c
+ gcc -fPIC -x c -O3 -c -DA_VERSION=1 -o a1.o a.c
+ gcc -fPIC -x c -O3 -c -o b.o b.c
+ gcc -fPIC -shared -o liba.dylib a0.o
+ ar rc liba.a a1.o
+ gcc -fPIC -shared -o libb.dylib b.o liba.a
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ab -Wl,liba.dylib -Wl,libb.dylib main.c
+ gcc -fPIE -x c -O3 -DA_VISIBILITY_DEFAULT -o ba -Wl,libb.dylib -Wl,liba.dylib main.c
+ ./ab
A : 0 - B : 1
+ ./ba
A : 0 - B : 1

With:

$ gcc --version
gcc (Debian 4.9.1-19) 4.9.1
Copyright (C) 2014 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.

Reported by malaterre on 2015-01-16 08:07:36

@gcode-importer
Copy link
Author

The scenario you describe is in comment #3:

[...]
which can lead to odd behaviour if an executable links against libfoo.so & libopenjp2.so
[...]

Are you sure the standard define a behavior for this use case ? Isn't it implementation
defined ? Anyway if this is UB, then feel free to apply the patch, since it seems to
do the right thing on clang/MacOSX (as seen on your console output).

Reported by malaterre on 2015-01-16 08:15:49

@gcode-importer
Copy link
Author

http://stackoverflow.com/a/9094015/136285

Reported by malaterre on 2015-01-16 10:50:08

@gcode-importer
Copy link
Author

I got my hand on multiple linux distribs today.
There are quite a lot of different behaviour for the first part... (including the same
as MacOs, The same as yours and others...).
On ubuntu 12.04, if you compile b object with -DA_VISIBILITY_DEFAULT in the first part
(the line that was commented out but shouldn't have been as it's more accurate in representing
OpenJPEG than the other line - guess I was wrong about visibility only applying when
building symbols), I get :
+ ./ab
A : 0 - B : 0
+ ./ba
A : 1 - B : 1
I wouldn't have thought so...

The only trick that seems to work on all distribs is the proposed one.
I'll get a patch for this.

Reported by mayeut on 2015-01-19 11:34:12

@gcode-importer
Copy link
Author

This issue was closed by revision r2994.

Reported by mayeut on 2015-01-25 16:59:42

  • Status changed: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant