46
46
47
47
# Ignore symbols that are exported as part of every executable
48
48
IGNORE_EXPORTS = {
49
- b '_edata' , b '_end' , b '_init' , b '__bss_start' , b '_fini' , b '_IO_stdin_used'
49
+ '_edata' , '_end' , '_init' , '__bss_start' , '_fini' , '_IO_stdin_used'
50
50
}
51
51
READELF_CMD = os .getenv ('READELF' , '/usr/bin/readelf' )
52
52
CPPFILT_CMD = os .getenv ('CPPFILT' , '/usr/bin/c++filt' )
53
53
# Allowed NEEDED libraries
54
54
ALLOWED_LIBRARIES = {
55
55
# bitcoind and bitcoin-qt
56
- b 'libgcc_s.so.1' , # GCC base support
57
- b 'libc.so.6' , # C library
58
- b 'libpthread.so.0' , # threading
59
- b 'libanl.so.1' , # DNS resolve
60
- b 'libm.so.6' , # math library
61
- b 'librt.so.1' , # real-time (clock)
62
- b 'ld-linux-x86-64.so.2' , # 64-bit dynamic linker
63
- b 'ld-linux.so.2' , # 32-bit dynamic linker
56
+ 'libgcc_s.so.1' , # GCC base support
57
+ 'libc.so.6' , # C library
58
+ 'libpthread.so.0' , # threading
59
+ 'libanl.so.1' , # DNS resolve
60
+ 'libm.so.6' , # math library
61
+ 'librt.so.1' , # real-time (clock)
62
+ 'ld-linux-x86-64.so.2' , # 64-bit dynamic linker
63
+ 'ld-linux.so.2' , # 32-bit dynamic linker
64
64
# bitcoin-qt only
65
- b 'libX11-xcb.so.1' , # part of X11
66
- b 'libX11.so.6' , # part of X11
67
- b 'libxcb.so.1' , # part of X11
68
- b 'libfontconfig.so.1' , # font support
69
- b 'libfreetype.so.6' , # font parsing
70
- b 'libdl.so.2' # programming interface to dynamic linker
65
+ 'libX11-xcb.so.1' , # part of X11
66
+ 'libX11.so.6' , # part of X11
67
+ 'libxcb.so.1' , # part of X11
68
+ 'libfontconfig.so.1' , # font support
69
+ 'libfreetype.so.6' , # font parsing
70
+ 'libdl.so.2' # programming interface to dynamic linker
71
71
}
72
72
73
73
class CPPFilt (object ):
@@ -77,10 +77,10 @@ class CPPFilt(object):
77
77
Use a pipe to the 'c++filt' command.
78
78
'''
79
79
def __init__ (self ):
80
- self .proc = subprocess .Popen (CPPFILT_CMD , stdin = subprocess .PIPE , stdout = subprocess .PIPE )
80
+ self .proc = subprocess .Popen (CPPFILT_CMD , stdin = subprocess .PIPE , stdout = subprocess .PIPE , universal_newlines = True )
81
81
82
82
def __call__ (self , mangled ):
83
- self .proc .stdin .write (mangled + b '\n ' )
83
+ self .proc .stdin .write (mangled + '\n ' )
84
84
self .proc .stdin .flush ()
85
85
return self .proc .stdout .readline ().rstrip ()
86
86
@@ -94,43 +94,43 @@ def read_symbols(executable, imports=True):
94
94
Parse an ELF executable and return a list of (symbol,version) tuples
95
95
for dynamic, imported symbols.
96
96
'''
97
- p = subprocess .Popen ([READELF_CMD , '--dyn-syms' , '-W' , executable ], stdout = subprocess .PIPE , stderr = subprocess .PIPE , stdin = subprocess .PIPE )
97
+ p = subprocess .Popen ([READELF_CMD , '--dyn-syms' , '-W' , executable ], stdout = subprocess .PIPE , stderr = subprocess .PIPE , stdin = subprocess .PIPE , universal_newlines = True )
98
98
(stdout , stderr ) = p .communicate ()
99
99
if p .returncode :
100
100
raise IOError ('Could not read symbols for %s: %s' % (executable , stderr .strip ()))
101
101
syms = []
102
- for line in stdout .split ( b' \n ' ):
102
+ for line in stdout .splitlines ( ):
103
103
line = line .split ()
104
- if len (line )> 7 and re .match (b '[0-9]+:$' , line [0 ]):
105
- (sym , _ , version ) = line [7 ].partition (b '@' )
106
- is_import = line [6 ] == b 'UND'
107
- if version .startswith (b '@' ):
104
+ if len (line )> 7 and re .match ('[0-9]+:$' , line [0 ]):
105
+ (sym , _ , version ) = line [7 ].partition ('@' )
106
+ is_import = line [6 ] == 'UND'
107
+ if version .startswith ('@' ):
108
108
version = version [1 :]
109
109
if is_import == imports :
110
110
syms .append ((sym , version ))
111
111
return syms
112
112
113
113
def check_version (max_versions , version ):
114
- if b '_' in version :
115
- (lib , _ , ver ) = version .rpartition (b '_' )
114
+ if '_' in version :
115
+ (lib , _ , ver ) = version .rpartition ('_' )
116
116
else :
117
117
lib = version
118
118
ver = '0'
119
- ver = tuple ([int (x ) for x in ver .split (b '.' )])
119
+ ver = tuple ([int (x ) for x in ver .split ('.' )])
120
120
if not lib in max_versions :
121
121
return False
122
122
return ver <= max_versions [lib ]
123
123
124
124
def read_libraries (filename ):
125
- p = subprocess .Popen ([READELF_CMD , '-d' , '-W' , filename ], stdout = subprocess .PIPE , stderr = subprocess .PIPE , stdin = subprocess .PIPE )
125
+ p = subprocess .Popen ([READELF_CMD , '-d' , '-W' , filename ], stdout = subprocess .PIPE , stderr = subprocess .PIPE , stdin = subprocess .PIPE , universal_newlines = True )
126
126
(stdout , stderr ) = p .communicate ()
127
127
if p .returncode :
128
128
raise IOError ('Error opening file' )
129
129
libraries = []
130
- for line in stdout .split ( b' \n ' ):
130
+ for line in stdout .splitlines ( ):
131
131
tokens = line .split ()
132
- if len (tokens )> 2 and tokens [1 ] == b '(NEEDED)' :
133
- match = re .match (b '^Shared library: \[(.*)\]$' , b ' ' .join (tokens [2 :]))
132
+ if len (tokens )> 2 and tokens [1 ] == '(NEEDED)' :
133
+ match = re .match ('^Shared library: \[(.*)\]$' , ' ' .join (tokens [2 :]))
134
134
if match :
135
135
libraries .append (match .group (1 ))
136
136
else :
@@ -144,18 +144,18 @@ def read_libraries(filename):
144
144
# Check imported symbols
145
145
for sym ,version in read_symbols (filename , True ):
146
146
if version and not check_version (MAX_VERSIONS , version ):
147
- print ('%s: symbol %s from unsupported version %s' % (filename , cppfilt (sym ). decode ( 'utf-8' ) , version . decode ( 'utf-8' ) ))
147
+ print ('%s: symbol %s from unsupported version %s' % (filename , cppfilt (sym ), version ))
148
148
retval = 1
149
149
# Check exported symbols
150
150
for sym ,version in read_symbols (filename , False ):
151
151
if sym in IGNORE_EXPORTS :
152
152
continue
153
- print ('%s: export of symbol %s not allowed' % (filename , cppfilt (sym ). decode ( 'utf-8' ) ))
153
+ print ('%s: export of symbol %s not allowed' % (filename , cppfilt (sym )))
154
154
retval = 1
155
155
# Check dependency libraries
156
156
for library_name in read_libraries (filename ):
157
157
if library_name not in ALLOWED_LIBRARIES :
158
- print ('%s: NEEDED library %s is not allowed' % (filename , library_name . decode ( 'utf-8' ) ))
158
+ print ('%s: NEEDED library %s is not allowed' % (filename , library_name ))
159
159
retval = 1
160
160
161
161
sys .exit (retval )
0 commit comments