Check for dynamic symbols required by an executable, categorizing them from the intermediate files that may have included those symbols.
(
nm: str, readelf: str, cxxfilt: str, binary_file: Path, build_root: Optional[Path]
)
| 241 | |
| 242 | |
| 243 | def check_dynamic( |
| 244 | nm: str, readelf: str, cxxfilt: str, binary_file: Path, build_root: Optional[Path] |
| 245 | ) -> int: |
| 246 | """Check for dynamic symbols required by an executable, categorizing them from the |
| 247 | intermediate files that may have included those symbols. |
| 248 | """ |
| 249 | symbols = get_cached_symbols(nm, build_root) if build_root is not None else {} |
| 250 | |
| 251 | dynamic_symbols = [] |
| 252 | binary_dyn_sym = get_binary_dynamic_symbols(readelf, binary_file) |
| 253 | for symbol in binary_dyn_sym: |
| 254 | if symbols is not None and symbol in symbols: |
| 255 | dynamic_symbols.append(symbols[symbol]) |
| 256 | else: |
| 257 | dynamic_symbols.append(Symbol(symbol, "", False, False, [])) |
| 258 | demangle_symbols(cxxfilt, dynamic_symbols) |
| 259 | check_disallowed_symbols(cxxfilt, dynamic_symbols) |
| 260 | |
| 261 | dynamic_by_file = {} |
| 262 | global_dynamic = [] |
| 263 | for symbol in dynamic_symbols: |
| 264 | if len(symbol.sources) == 0: |
| 265 | global_dynamic.append(symbol) |
| 266 | continue |
| 267 | |
| 268 | for file in symbol.sources: |
| 269 | if file not in dynamic_by_file: |
| 270 | dynamic_by_file[file] = [] |
| 271 | dynamic_by_file[file].append(symbol) |
| 272 | |
| 273 | print("Executable relies on the following dynamic symbols:") |
| 274 | for file, symbols in dynamic_by_file.items(): |
| 275 | print(f"{file} contains dynamic symbols:") |
| 276 | for symbol in symbols: |
| 277 | print(" *", symbol.demangled) |
| 278 | print() |
| 279 | |
| 280 | if len(dynamic_by_file) > 0: |
| 281 | return STATUS_ERROR |
| 282 | |
| 283 | return STATUS_OK |
| 284 | |
| 285 | |
| 286 | def bubble_error(program_status, routine_status) -> int: |
no test coverage detected