MCPcopy
hub / github.com/tinygrad/tinygrad / elf_loader

Function elf_loader

tinygrad/runtime/support/elf.py:15–50  ·  view source on GitHub ↗
(blob:bytes, force_section_align:int=1, link_libs:list[str]|None=None)

Source from the content-addressed store, hash-verified

13 raise RuntimeError(f'Attempting to relocate against an undefined symbol {sym}')
14
15def elf_loader(blob:bytes, force_section_align:int=1, link_libs:list[str]|None=None) -> tuple[memoryview, list[ElfSection], list[tuple]]:
16 assert blob[:4] == libc.ELFMAG.encode(), "blob is not an ELF, missing magic bytes"
17 ecls = {libc.ELFCLASS32: "Elf32", libc.ELFCLASS64: "Elf64"}[blob[libc.EI_CLASS]]
18
19 def _strtab(blob: bytes, idx: int) -> str: return blob[idx:blob.find(b'\x00', idx)].decode('utf-8')
20
21 header = getattr(libc, f"{ecls}_Ehdr").from_buffer_copy(blob)
22 section_headers = (getattr(libc, f"{ecls}_Shdr") * header.e_shnum).from_buffer_copy(blob[header.e_shoff:])
23 sh_strtab = blob[(shstrst:=section_headers[header.e_shstrndx].sh_offset):shstrst+section_headers[header.e_shstrndx].sh_size]
24 sections = [ElfSection(_strtab(sh_strtab, sh.sh_name), sh, blob[sh.sh_offset:sh.sh_offset+sh.sh_size]) for sh in section_headers]
25
26 def _to_carray(sh, ctype): return (ctype * (sh.header.sh_size // sh.header.sh_entsize)).from_buffer_copy(sh.content)
27 rel = [(sh, sh.name[4:], _to_carray(sh, getattr(libc, f"{ecls}_Rel"))) for sh in sections if sh.header.sh_type == libc.SHT_REL]
28 rela = [(sh, sh.name[5:], _to_carray(sh, getattr(libc, f"{ecls}_Rela"))) for sh in sections if sh.header.sh_type == libc.SHT_RELA]
29 symtab = next((_to_carray(sh, getattr(libc, f"{ecls}_Sym")) for sh in sections if sh.header.sh_type == libc.SHT_SYMTAB), None)
30 progbits = [sh for sh in sections if sh.header.sh_type == libc.SHT_PROGBITS]
31
32 # Prealloc image for all fixed addresses.
33 image = bytearray(max([sh.header.sh_addr + sh.header.sh_size for sh in progbits if sh.header.sh_addr != 0] + [0]))
34 for sh in progbits:
35 if sh.header.sh_addr != 0: image[sh.header.sh_addr:sh.header.sh_addr+sh.header.sh_size] = sh.content
36 else:
37 image += b'\0' * (((align:=max(sh.header.sh_addralign, force_section_align)) - len(image) % align) % align) + sh.content
38 sh.header.sh_addr = len(image) - len(sh.content)
39
40 # Relocations
41 relocs = []
42 for sh, trgt_sh_name, c_rels in rel + rela:
43 if trgt_sh_name == ".eh_frame": continue
44 target_image_off = next(tsh for tsh in sections if tsh.name == trgt_sh_name).header.sh_addr
45 rels = [(r.r_offset, unwrap(symtab)[getattr(libc, f"{ecls.upper()}_R_SYM")(r.r_info)], getattr(libc, f"{ecls.upper()}_R_TYPE")(r.r_info),
46 getattr(r, "r_addend", 0)) for r in c_rels]
47 relocs += [(target_image_off + roff, link_sym(_strtab(sh_strtab, sym.st_name), link_libs or []) if sym.st_shndx == 0 else
48 sections[sym.st_shndx].header.sh_addr + sym.st_value, rtype, raddend) for roff, sym, rtype, raddend in rels]
49
50 return memoryview(image), sections, relocs
51
52def jit_loader(obj: bytes, base:int=0, link_libs:list[str]|None=None) -> bytes:
53 image_, _, relocs = elf_loader(obj, link_libs=link_libs)

Callers 15

__init__Method · 0.90
__init__Method · 0.90
init_fmc_imageMethod · 0.90
init_gsp_imageMethod · 0.90
get_elf_sectionFunction · 0.90
amd_build_programFunction · 0.90
custom_fa_forwardFunction · 0.90
custom_fa_backward_preFunction · 0.90
custom_fa_backwardFunction · 0.90
custom_fa_backward_postFunction · 0.90
test_linkMethod · 0.90

Calls 6

unwrapFunction · 0.90
ElfSectionClass · 0.85
_strtabFunction · 0.85
_to_carrayFunction · 0.85
link_symFunction · 0.85
encodeMethod · 0.45

Tested by 6

test_linkMethod · 0.72
run_rocprof_decoderFunction · 0.72
_get_kernel_codeMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…