[Kong API].internal.image_interface

Data mapping templates and image_interface class


Synopsis:

typeof(A) __map__(alias A, T = typeof(A))(image_interface, uint n);
typeof(A) __map__(alias A, T = typeof(A))(image_interface, uint n, uint offset);
void      __unmap__(alias A)(image_interface);

Description:

These mapping templates provide an opaque method for extracting and modifying data blocks from executable images. They are non-copying for memory based Streams - the mapped data points directly to the original. For file based streams a memory block (copy_block) is allocated and tagged so image_interface.commit() can write them back to disk. The size of the base datatype is inferred from typeof(A) (if not explicity set) and is combined with "n" to calculate the raw block length in bytes.

The result is stored in the variable of the first template parameter and as the return value.

  • Note: the 'A' parameter should be a blank dynamic array or pointer.
  • Note: image_interface.commit() blindly copies each block back to disk without checking for overlapping regions etc.
  • Bug: these functions should be inside the image_interface class but were forced out due to aliasing.

Example:

struct x { ubyte[256] buf; }

x[] A;
x[] B;

char[] str;

__map__!(A)(image, 2);

B = cast(x[]) __map__!(B, byte)(image, 512);

assert(A.length == 2); // pass
assert(B.length == 2); // pass

foreach (c; __map__!(str)(image, 10))
    writefln("%c", c);

class : image_interface

Type Name Description
Constructors:
(Stream) this Supported Streams: CoreStream?, File, MemoryStream, MmFileStream
Data:
Stream file
copy_block[uintptr_t] memory Data allocated with file based streams.
Methods:
string (size_t offset) read_stringz Read at offset until 0x0 is reached.
string () read_stringz Read from current file position until 0x0.
T (T)(size_t offset) read Copy T.sizeof at offset to T.
T (T)() read Copy T.sizeof from current file position to T.
void (T)(in T data) write
void (T)(in T data, size_t offset) write
void () commit Record all copy_blocks from this.memory back to file.
aligned_block (size_t size, size_t alignment) aligned_extend Extend file so that theres room for size bytes starting on aligned boundry.
Static Methods:
uintptr_t (uintptr_t a, uintptr_t b) align_to Align A to B boundry.
  • The six I/O functions here all copy, and do not flag the memory for commit().
  • Use __map__ instead for non-trivial blocks of data.

Related:

ELF, PE