As we have seen mapping variables is a very powerful, general and flexible mean to edit stored binary data in one or more IO spaces. However it is easy to lose track of where the variables are mapped and, ideally speaking, we would want to have a mean to refer to, say, the “ELF header”, and get the header as a mapped value regardless of what specific file we are editing. Sort of a “meta variable”. GNU poke provides a way to do this: maps.
A map can be conceived as a sort of “view” that can be applied to a given IO space. Maps have entries, which are values mapped at some given offset, under certain conditions. For example, we have seen an ELF file contains, among other things, a header at the beginning of the file and a table of section headers of certain size and located at certain location determined by the header. These would be two entries of a so-called ELF map.
poke maps are defined in map files. These files use the
.map extension. A map file
sectioned/simple elf) defining the view of an ELF file as a header and
a table of section header would look like this:
/* self.map - map file for a simplified view of an ELF file. */ load elf; %% %entry %name ehdr %type Elf64_Ehdr %offset 0#B %entry %name shdr %type Elf64_Shdr[(Elf64_Ehdr @ 0#B).e_shnum] %condition (Elf64_Ehdr @ 0#B).e_shnum > 0 %offset (Elf64_Ehdr @ 0#B).e_shoff
This map file defines a view of an ELF file as a header entry
ehdr and an entry with a table of section headers
The first section of the file, which spans until the separator line
%%, is arbitrary Poke code which as we shall see,
gets evaluated before the map entries are processed. This is called
the map "prologue". In this case, the prologue contains a comment
explaining the purpose of the file, and a single statement
that loads the
elf.pk pickle, since the entries below use
Elf64_Ehdr that are defined by that pickle.
The prologue is useful to define Poke functions and other entities
that are then used in the definitions of the entries.
A separator line containing only
%% separates the prologue from
the next section, which is a list of entries definitions. Each entry
definition starts with a line
%entry, and has the following
shdr. These names should follow the same
rules than Poke variables, but as we shall see later, map entries are
not Poke variables. This attribute is mandatory.
This can be any Poke expression denoting a type, like
Elf64_Shdr[(Elf64_Ehdr @ 0#B).e_shnum].
This attribute is mandatory.
If specified, will determine whether to include the entry in the map.
In the example above, the map will have an entry
shdr only if the
ELF file has one or more sections. Any Poke expression evaluating to
a boolean can be used as conditions. This attribute is optional:
entries not having a condition will always be included in the map.
Offset in the IO space where the entry will be mapped. Any Poke expression evaluating to an offset can be used as entry offset. This attribute is mandatory.