All files / binary101/analyzers/elf tls.ts

100% Statements 39/39
87.5% Branches 14/16
100% Functions 2/2
100% Lines 39/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 411x 1x 1x 1x 1x 1x 1x 1x 384x 384x 384x 1x 1x 91x 91x 91x 22x 22x 22x 22x 22x 22x 91x 91x 91x 91x 91x 91x 22x 22x 22x 22x 22x 22x 91x 91x 91x 88x 91x    
"use strict";
 
import type { ElfProgramHeader, ElfSectionHeader, ElfTlsInfo } from "./types.js";
 
const PT_TLS = 7;
const SHF_TLS = 0x400;
 
const hasTlsFlag = (sec: ElfSectionHeader): boolean => {
  const flags = typeof sec.flags === "bigint" ? sec.flags : BigInt(sec.flags);
  return (flags & BigInt(SHF_TLS)) !== 0n;
};
 
export function parseElfTlsInfo(programHeaders: ElfProgramHeader[], sections: ElfSectionHeader[]): ElfTlsInfo | null {
  const segments = programHeaders
    .filter(ph => ph.type === PT_TLS && ph.memsz > 0n)
    .map(ph => ({
      index: ph.index,
      offset: ph.offset,
      vaddr: ph.vaddr,
      filesz: ph.filesz,
      memsz: ph.memsz,
      align: ph.align
    }));
 
  const tlsSections = sections
    .filter(sec => sec.size > 0n)
    .filter(sec => hasTlsFlag(sec) || sec.name === ".tdata" || sec.name === ".tbss")
    .map(sec => ({
      index: sec.index,
      name: sec.name || "",
      addr: sec.addr,
      offset: sec.offset,
      size: sec.size,
      flags: sec.flagNames
    }));
 
  if (!segments.length && !tlsSections.length) return null;
  return { segments, sections: tlsSections };
}