1 |
When support for parsing ELF headers in order to compute multilib |
2 |
category was added in commit f1c1b8a77eebf7713b32e5f9945690f60f4f46de, |
3 |
the LinkageMapELF class was not updated to do the same for preserved |
4 |
libraries. This has resulted in incorrect preserve-libs handling |
5 |
as reported in bug 598080, for ABIs including x32 where the |
6 |
_approx_multilib_categories mapping is insufficient. This patch fixes |
7 |
LinkageMapELF to compute the multilib category for each preserved |
8 |
library, in the same way as the _post_src_install_soname_symlinks |
9 |
function, so that the LinkageMapELF.findConsumers method will operate |
10 |
correctly with preserved libraries of all ABIs. |
11 |
|
12 |
Fixes: f1c1b8a77eeb ("Generate soname dependency metadata (bug 282639)") |
13 |
X-Gentoo-bug: 598080 |
14 |
X-Gentoo-bug-url: https://bugs.gentoo.org/598080 |
15 |
--- |
16 |
pym/portage/util/_dyn_libs/LinkageMapELF.py | 33 +++++++++++++++++++++++------ |
17 |
1 file changed, 26 insertions(+), 7 deletions(-) |
18 |
|
19 |
diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py b/pym/portage/util/_dyn_libs/LinkageMapELF.py |
20 |
index 0b09fe5..a063621 100644 |
21 |
--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py |
22 |
+++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py |
23 |
@@ -4,6 +4,7 @@ |
24 |
import errno |
25 |
import logging |
26 |
import subprocess |
27 |
+import sys |
28 |
|
29 |
import portage |
30 |
from portage import _encodings |
31 |
@@ -12,6 +13,7 @@ from portage import _unicode_decode |
32 |
from portage import _unicode_encode |
33 |
from portage.cache.mappings import slot_dict_class |
34 |
from portage.const import EPREFIX |
35 |
+from portage.dep.soname.multilib_category import compute_multilib_category |
36 |
from portage.exception import CommandNotFound, InvalidData |
37 |
from portage.localization import _ |
38 |
from portage.util import getlibpaths |
39 |
@@ -20,6 +22,12 @@ from portage.util import normalize_path |
40 |
from portage.util import varexpand |
41 |
from portage.util import writemsg_level |
42 |
from portage.util._dyn_libs.NeededEntry import NeededEntry |
43 |
+from portage.util.elf.header import ELFHeader |
44 |
+ |
45 |
+if sys.hexversion >= 0x3000000: |
46 |
+ _unicode = str |
47 |
+else: |
48 |
+ _unicode = unicode |
49 |
|
50 |
# Map ELF e_machine values from NEEDED.ELF.2 to approximate multilib |
51 |
# categories. This approximation will produce incorrect results on x32 |
52 |
@@ -283,15 +291,26 @@ class LinkageMapELF(object): |
53 |
l = l[3:].rstrip("\n") |
54 |
if not l: |
55 |
continue |
56 |
- fields = l.split(";") |
57 |
- if len(fields) < 5: |
58 |
- writemsg_level(_("\nWrong number of fields " \ |
59 |
- "returned from scanelf: %s\n\n") % (l,), |
60 |
+ try: |
61 |
+ entry = NeededEntry.parse("scanelf", l) |
62 |
+ except InvalidData as e: |
63 |
+ writemsg_level("\n%s\n\n" % (e,), |
64 |
level=logging.ERROR, noiselevel=-1) |
65 |
continue |
66 |
- fields[1] = fields[1][root_len:] |
67 |
- owner = plibs.pop(fields[1], None) |
68 |
- lines.append((owner, "scanelf", ";".join(fields))) |
69 |
+ try: |
70 |
+ with open(_unicode_encode(entry.filename, |
71 |
+ encoding=_encodings['fs'], |
72 |
+ errors='strict'), 'rb') as f: |
73 |
+ elf_header = ELFHeader.read(f) |
74 |
+ except EnvironmentError as e: |
75 |
+ if e.errno != errno.ENOENT: |
76 |
+ raise |
77 |
+ # File removed concurrently. |
78 |
+ continue |
79 |
+ entry.multilib_category = compute_multilib_category(elf_header) |
80 |
+ entry.filename = entry.filename[root_len:] |
81 |
+ owner = plibs.pop(entry.filename, None) |
82 |
+ lines.append((owner, "scanelf", _unicode(entry))) |
83 |
proc.wait() |
84 |
proc.stdout.close() |
85 |
|
86 |
-- |
87 |
2.7.4 |