#!/usr/bin/env python3 """The ELF extractor must follow *sections*, not program headers. lld maps the ELF header and program-header table as a LOAD of its own -- 52 + 4x32 = 180 bytes at the image base, with no section content in it. An extractor that follows program headers therefore puts a phantom 180-byte region below the first real section, and the image is refused with APP_ERR_VMA or, worse, built from the wrong base. These tests build the ELFs by hand, so they need no toolchain. """ import struct import unittest import os import tempfile import elf2bin def build_elf(body=b"\x11" * 64, with_phantom_phdr=False): """A minimal 32-bit little-endian ELF with one allocated section holding @body. With @with_phantom_phdr the first program header is a LOAD covering the ELF header and the program-header table itself -- no section content, exactly what lld emits -- which must not become part of the extracted image. """ ehsize, phentsize, shentsize = 52, 32, 40 phnum = 2 if with_phantom_phdr else 1 phoff = ehsize data_off = phoff + phnum * phentsize shoff = data_off + len(body) blob = bytearray(shoff + shentsize) blob[0:4] = b"\x7fELF" blob[4] = 1 # 32-bit blob[5] = 1 # little endian struct.pack_into("