| #!/usr/bin/env python3 |
| # |
| # Copyright (c) 2024 STMicroelectronics |
| # SPDX-License-Identifier: Apache-2.0 |
| |
| """ |
| This file implements the Symbol Link Identifer (SLID) |
| generation code, for use by the LLEXT subsystem. |
| SLID-based linking is enabled by the Kconfig |
| option 'CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID'. |
| |
| When executed as a script, this file can be used as |
| an interactive prompt to calculate the SLID of arbitrary |
| symbols, which can be useful for debugging purposes. |
| |
| IMPLEMENTATION NOTES: |
| Currently, SLIDs are generated by taking the first |
| [pointer size] bytes of the symbol name's SHA-256 |
| hash, taken in big-endian order. |
| |
| This ordering provides one advantage: the 32-bit |
| SLID for an export is present in the top 32 bits of |
| the 64-bit SLID for the same export. |
| """ |
| |
| from hashlib import sha256 |
| |
| def generate_slid(symbol_name: str, slid_size: int) -> int: |
| """ |
| Generates the Symbol Link Identifier (SLID) for a symbol. |
| |
| symbol_name: Name of the symbol for which to generate a SLID |
| slid_side: Size of the SLID in bytes (4/8) |
| """ |
| if slid_size not in (4, 8): |
| raise AssertionError(f"Invalid SLID size {slid_size}") |
| |
| m = sha256() |
| m.update(symbol_name.encode("utf-8")) |
| hash = m.digest() |
| return int.from_bytes(hash[0:slid_size], byteorder='big', signed=False) |
| |
| def format_slid(slid: int, slid_size: int) -> str: |
| if slid_size == 4: |
| fmt = f"0x{slid:08X}" |
| elif slid_size == 8: |
| fmt = f"0x{slid:016X}" |
| return fmt |
| |
| def repl(): |
| while True: |
| sym_name = input("Symbol name? ") |
| slid32 = generate_slid(sym_name, 4) |
| slid64 = generate_slid(sym_name, 8) |
| print(f" 32-bit SLID for '{sym_name}': {format_slid(slid32, 4)}") |
| print(f" 64-bit SLID for '{sym_name}': {format_slid(slid64, 8)}") |
| print() |
| |
| if __name__ == "__main__": |
| print("LLEXT SLID calculation REPL") |
| print("Press ^C to exit.") |
| try: |
| repl() |
| except KeyboardInterrupt: |
| print() |