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