elf.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. from typing import BinaryIO
  10. # `stubgen -p elftools` doesn't work out of the box,
  11. # and manually writing stub files for all of `elftools`
  12. # seems like a large and error-prone project.
  13. #
  14. # If we start using pyelftools from more places, it might be useful to
  15. # have a stub file. A sketch of one can be found here:
  16. # https://github.com/MaterializeInc/materialize/pull/19960#discussion_r1231516060
  17. from elftools.elf.elffile import ELFFile, NoteSection # type: ignore
  18. from materialize.ui import UIError
  19. def get_build_id(file: BinaryIO) -> str:
  20. elf_file = ELFFile(file)
  21. build_id_section = elf_file.get_section_by_name(".note.gnu.build-id")
  22. if not build_id_section:
  23. raise UIError(f"ELF file has no .note.gnu.build-id section: {file}")
  24. if not isinstance(build_id_section, NoteSection):
  25. raise UIError(f"ELF file .note.gnu.build-id section could not be read: {file}")
  26. for note in build_id_section.iter_notes():
  27. if note.n_type == "NT_GNU_BUILD_ID" and note.n_name == "GNU":
  28. return str(note.n_desc)
  29. raise UIError(f"ELF file GNU build ID could not be found: {file}")