commit:     23266acb57647d14254f5cefe6afcd362e30cdd3
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Fri Dec  5 19:09:21 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Dec  5 19:09:21 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/blas-lapack-aux-wrapper.git/commit/?id=23266acb

Switch to readelf and improve symbol filtering

Emit only symbols corresponding to defined functions.  Use readelf(1)
rather than nm(1), since the latter reports the section types for
symbols rather than the actual symbol types.  Thanks to Alexander
Monakov for the suggestion.

Bug: https://bugs.gentoo.org/967081
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 make-symbol-files.py | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/make-symbol-files.py b/make-symbol-files.py
index 86cbeb2..74881b1 100755
--- a/make-symbol-files.py
+++ b/make-symbol-files.py
@@ -10,11 +10,32 @@ from typing import Generator
 
 
 def get_symbols(path: Path) -> Generator[str]:
-    for line in subprocess.run(["nm", "-D", "-P", "-U", str(path)],
-                               stdout=subprocess.PIPE,
-                               check=True).stdout.decode().splitlines():
-        sym, _ = line.split(" ", 1)
-        yield sym
+    it = iter(subprocess.run(["readelf", "-W", "--dyn-syms", str(path)],
+                             stdout=subprocess.PIPE,
+                             check=True).stdout.decode().splitlines())
+    for line in it:
+        if line.startswith("Symbol table"):
+            break
+    else:
+        raise RuntimeError("Symbol table output not found in readelf output!")
+
+    header = next(it)
+    _num, _value, _size, typ, bind, vis, ndx, name = header.split()
+    assert typ == "Type"
+    assert bind == "Bind"
+    assert vis == "Vis"
+    assert ndx == "Ndx"
+    assert name == "Name"
+
+    for line in it:
+        _num, _value, _size, typ, bind, vis, ndx, *rest = line.split()
+        if typ != "FUNC" or ndx == "UND":
+            continue
+        assert bind in ("GLOBAL", "WEAK")
+        assert vis in ("DEFAULT", "PROTECTED")
+        name, *_ = rest
+        assert "@" not in name
+        yield name
 
 
 def main():

Reply via email to