| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Unison.Runtime.Bundle.MachO
Description
A bundle's program inside a Mach-O executable (macOS), in the section
UNISON,uc (see Unison.Runtime.Bundle).
A Mach-O executable is a header, a list of load commands, and the bytes
of its segments, in order. Each segment's load command says where its
bytes are in the file (fileoff, filesize) and in memory (vmaddr,
vmsize), and lists its sections. The last segment is always
__LINKEDIT: the symbol table, the dynamic loader's information and the
code signature, which other load commands point into by file offset.
unisonrt is linked with -sectcreate UNISON uc, so that the segment
__UNISON, holding that one section, is the segment right before
__LINKEDIT, in the file and in memory. That makes the section the one
place that can grow without moving any code or data: growing it moves
only __LINKEDIT, which no code refers to by address, and the load
commands say where __LINKEDIT and everything in it now is. Since the
program is then part of the image, the code signature covers it, once
the executable is signed again.
Field offsets are from mach-o/loader.h.
Synopsis
- isMachO :: ByteString -> Bool
- programSection :: ByteString -> Maybe ByteString
- setProgramSection :: ByteString -> ByteString -> Either String ByteString
Documentation
isMachO :: ByteString -> Bool Source #
Whether these are the bytes of a 64-bit little-endian Mach-O file (arm64 and x86-64 macOS)
programSection :: ByteString -> Maybe ByteString Source #
The contents of the section UNISON,uc, if the file has it
setProgramSection :: ByteString -> ByteString -> Either String ByteString Source #
The file with the section UNISON,uc holding these contents
instead. Its code signature no longer matches; the caller signs it
again. The steps:
- Find the segment
__UNISONand its section, and check that the segment is the one right before__LINKEDIT, in the file and in memory. - The segment's new size: from its start to the end of the new contents, in whole pages, since segments are mapped by page.
__LINKEDITmoves to just after it, in the file and in memory, by the change in that size.- The load commands are patched: the segment's sizes and the section's,
__LINKEDIT's place, and every file offset another load command holds into__LINKEDIT(linkEditOffsetFields). - The new file is the bytes before the segment (with the patched load
commands, which are among them), the segment's new bytes, and
__LINKEDIT's bytes, unchanged.