checkSoAlignment function

ElfAlignmentResult checkSoAlignment(
  1. String path,
  2. List<int> bytes
)

Reads path's ELF program headers (32-bit or 64-bit, either endianness) and checks every PT_LOAD segment's alignment against requiredLoadSegmentAlignment (SPEC ยง3.1.2).

Implementation

ElfAlignmentResult checkSoAlignment(String path, List<int> bytes) {
  if (bytes.length < 6 ||
      bytes[0] != _elfMagic[0] ||
      bytes[1] != _elfMagic[1] ||
      bytes[2] != _elfMagic[2] ||
      bytes[3] != _elfMagic[3]) {
    throw NotElfException(path);
  }
  final is64Bit = bytes[4] == 2;
  final endian = bytes[5] == 2 ? Endian.big : Endian.little;
  final data = ByteData.sublistView(Uint8List.fromList(bytes));

  final int phoff;
  final int phentsize;
  final int phnum;
  if (is64Bit) {
    phoff = data.getUint64(32, endian);
    phentsize = data.getUint16(54, endian);
    phnum = data.getUint16(56, endian);
  } else {
    phoff = data.getUint32(28, endian);
    phentsize = data.getUint16(42, endian);
    phnum = data.getUint16(44, endian);
  }

  int? minAlignment;
  for (var i = 0; i < phnum; i++) {
    final headerOffset = phoff + i * phentsize;
    final pType = data.getUint32(headerOffset, endian);
    if (pType != _ptLoad) continue;
    final pAlign = is64Bit
        ? data.getUint64(headerOffset + 48, endian)
        : data.getUint32(headerOffset + 28, endian);
    if (minAlignment == null || pAlign < minAlignment) {
      minAlignment = pAlign;
    }
  }

  return ElfAlignmentResult(
    path: path,
    aligned:
        minAlignment == null || minAlignment >= requiredLoadSegmentAlignment,
    minLoadSegmentAlignment: minAlignment,
  );
}