1 |
On 02/25/2015 04:07 PM, Zac Medico wrote: |
2 |
> On 02/25/2015 03:41 PM, Anthony G. Basile wrote: |
3 |
>> On 02/25/15 15:38, Zac Medico wrote: |
4 |
>>> On 02/25/2015 12:01 PM, Anthony G. Basile wrote: |
5 |
>>>> On 02/25/15 14:51, Anthony G. Basile wrote: |
6 |
>>>>> On 02/22/15 01:30, Zac Medico wrote: |
7 |
>>>>>> On 02/21/2015 10:22 PM, Zac Medico wrote: |
8 |
>>>>>>> If we put the real/canonical libstdc++.so path in the DT_NEEDED |
9 |
>>>>>>> section, |
10 |
>>>>>>> then it will automatically work with existing soname dependency |
11 |
>>>>>>> support. |
12 |
>>>>>> |
13 |
>>>>>> Actually, we'd also have to add a way for you to put the full path of |
14 |
>>>>>> the libstdc++.so in PROVIDES. For example: |
15 |
>>>>>> |
16 |
>>>>>> PROVIDES_ABSOLUTE="/usr/lib/gcc/*/*/libstdc++.so.6" |
17 |
>>>>>> |
18 |
>>>>> |
19 |
>>>>> I guess I don't understand how this would work exactly. What if |
20 |
>>>>> someone |
21 |
>>>>> has gcc-4.8.3. Builds library libfoo.so which uses c++. Then upgrades |
22 |
>>>>> to gcc-4.9, removes 4.8 and then tries to build bar which is also |
23 |
>>>>> written in c++ and links against libfoo.so. We would have mismatching |
24 |
>>>>> abis. How would this catch it and trigger the correct rebuilds? |
25 |
>>>>> |
26 |
>>>>> Unless I'm misunderstanding your *'s in that line. Are you using |
27 |
>>>>> PROVIDES_ABSOLUTE as a way of recording what version of the compiler |
28 |
>>>>> libfoo.so was build with? So that you'd have a line that says |
29 |
>>>>> libfoo.so |
30 |
>>>>> links against /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so, so |
31 |
>>>>> that parsing that line gives 4.8.3? |
32 |
>>>>> |
33 |
>>>>> Also if you had the absolute path in VDB somewhere, like in PROVIDES, |
34 |
>>>>> then you don't need it in the elf's rpath which would make me feel |
35 |
>>>>> better. |
36 |
>>>>> |
37 |
>>>> |
38 |
>>>> Actually no, you'd still need rpath for the elf itslef otherwise you can |
39 |
>>>> still link against the wrong version of libstdc++.so. Note in my |
40 |
>>>> following example that even though I build test.cpp with 4.7.3 I still |
41 |
>>>> wind up linking aginast 4.8.3. |
42 |
>>> |
43 |
>>> If DT_NEEDED contains the absolute libstdc++.so path, it's guaranteed to |
44 |
>>> link against the correct version, regardless of rpath. |
45 |
>>> |
46 |
>> |
47 |
>> How do you get DT_NEEDED to the absolute libstdc++.so path when building? |
48 |
> |
49 |
> I'm not sure how we're going to accomplish that yet, but it should be |
50 |
> feasible. Ideally, the build system would support it. The worst case |
51 |
> would be that we would have to patch the DT_NEEDED sections after |
52 |
> src_install. |
53 |
|
54 |
Using patchelf built from git [1], I tried to patch the DT_NEEDED of a |
55 |
"hello world" program: |
56 |
$ cat hello.cpp |
57 |
#include <iostream> |
58 |
using namespace std; |
59 |
int main() { cout << "Hello World!" << endl ; } |
60 |
$ g++ -o hello hello.cpp |
61 |
$ scanelf -qF '%a;%p;%S;%r;%n' hello |
62 |
EM_X86_64;hello;;;libstdc++.so.6,libm.so.6,libgcc_s.so.1,libc.so.6 |
63 |
$ ldd hello |
64 |
linux-vdso.so.1 (0x00007fff5992a000) |
65 |
libstdc++.so.6 => |
66 |
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so.6 (0x00007f38f6a82000) |
67 |
libm.so.6 => /lib64/libm.so.6 (0x00007f38f6783000) |
68 |
libgcc_s.so.1 => |
69 |
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libgcc_s.so.1 (0x00007f38f656d000) |
70 |
libc.so.6 => /lib64/libc.so.6 (0x00007f38f61c7000) |
71 |
/lib64/ld-linux-x86-64.so.2 (0x00007f38f6d86000) |
72 |
$ ./hello |
73 |
Hello World! |
74 |
$ patchelf --replace-needed libstdc++.so.6 |
75 |
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so.6 hello |
76 |
$ scanelf -qF '%a;%p;%S;%r;%n' hello |
77 |
EM_X86_64;hello;;;/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so.6,libm.so.6,libgcc_s.so.1,libc.so.6 |
78 |
$ ldd hello |
79 |
Inconsistency detected by ld.so: dl-version.c: 224: |
80 |
_dl_check_map_versions: Assertion `needed != ((void *)0)' failed! |
81 |
$ ./hello |
82 |
Inconsistency detected by ld.so: dl-version.c: 224: |
83 |
_dl_check_map_versions: Assertion `needed != ((void *)0)' failed! |
84 |
|
85 |
Apparently the ld.so is not capable of resolving absolute paths in |
86 |
DT_NEEDED. Maybe it's more practical to go with -rpath instead. |
87 |
|
88 |
[1] https://github.com/NixOS/patchelf |
89 |
-- |
90 |
Thanks, |
91 |
Zac |