misc.python.materialize.elf

 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
10from typing import BinaryIO
11
12# `stubgen -p elftools` doesn't work out of the box,
13# and manually writing stub files for all of `elftools`
14# seems like a large and error-prone project.
15#
16# If we start using pyelftools from more places, it might be useful to
17# have a stub file. A sketch of one can be found here:
18# https://github.com/MaterializeInc/materialize/pull/19960#discussion_r1231516060
19from elftools.elf.elffile import ELFFile, NoteSection  # type: ignore
20
21from materialize.ui import UIError
22
23
24def get_build_id(file: BinaryIO) -> str:
25    elf_file = ELFFile(file)
26
27    build_id_section = elf_file.get_section_by_name(".note.gnu.build-id")
28
29    if not build_id_section:
30        raise UIError(f"ELF file has no .note.gnu.build-id section: {file}")
31
32    if not isinstance(build_id_section, NoteSection):
33        raise UIError(f"ELF file .note.gnu.build-id section could not be read: {file}")
34
35    for note in build_id_section.iter_notes():
36        if note.n_type == "NT_GNU_BUILD_ID" and note.n_name == "GNU":
37            return str(note.n_desc)
38
39    raise UIError(f"ELF file GNU build ID could not be found: {file}")
def get_build_id(file: <class 'BinaryIO'>) -> str:
25def get_build_id(file: BinaryIO) -> str:
26    elf_file = ELFFile(file)
27
28    build_id_section = elf_file.get_section_by_name(".note.gnu.build-id")
29
30    if not build_id_section:
31        raise UIError(f"ELF file has no .note.gnu.build-id section: {file}")
32
33    if not isinstance(build_id_section, NoteSection):
34        raise UIError(f"ELF file .note.gnu.build-id section could not be read: {file}")
35
36    for note in build_id_section.iter_notes():
37        if note.n_type == "NT_GNU_BUILD_ID" and note.n_name == "GNU":
38            return str(note.n_desc)
39
40    raise UIError(f"ELF file GNU build ID could not be found: {file}")