Loader for position-independent images with absolute relocations.
More...
|
| typedef int(* | pbl_loader_read_t) (void *ctx, size_t offset, void *buf, size_t len) |
| | Read bytes from an image source.
|
| |
| typedef uint32_t(* | pbl_loader_address_t) (void *ctx, const void *addr) |
| | Translate an address in the loaded image to the address the image code sees.
|
| |
Loader for position-independent images with absolute relocations.
An image is linked at address 0 and stored as its file part (code and data) followed, at any offset of the source, by a relocation table. Each table entry is the little-endian 32-bit offset of a 32-bit slot in the file part; the slot holds an image offset, and the loader adds the address the image was loaded at to it. The memory past the file part, up to the memory size, is zero-filled.
Loading happens in two steps, so the caller can check the copied bytes (e.g. a checksum) before relocations change them:
if (ret < 0) {
return ret;
}
int pbl_loader_copy(const struct pbl_loader_image *img, const struct pbl_loader_source *src, void *dst, size_t dst_size)
Copy the file part of an image and zero-fill the rest of its memory.
int pbl_loader_relocate(const struct pbl_loader_image *img, const struct pbl_loader_source *src, void *dst, size_t dst_size, pbl_loader_address_t address, void *ctx)
Apply the relocations of an image copied by pbl_loader_copy().
Slots and table entries do not need to be aligned. Every entry and slot value is checked against the image, so a malformed image cannot write outside of it.
◆ pbl_loader_source
◆ pbl_loader_image
| Data Fields |
|
size_t |
file_size |
Size of the file part, stored at source offset 0. |
|
size_t |
header_size |
Size of the header at the start of the file part, which relocations must not target. |
|
size_t |
mem_size |
Size of the image in memory, file part plus zero-fill. |
|
size_t |
reloc_count |
Number of relocation table entries. |
|
size_t |
reloc_offset |
Source offset of the relocation table. |
◆ pbl_loader_address_t
| typedef uint32_t(* pbl_loader_address_t) (void *ctx, const void *addr) |
Translate an address in the loaded image to the address the image code sees.
- Parameters
-
| ctx | Translation context. |
| addr | Address in the destination buffer. |
- Returns
- Address the image code uses for
addr.
◆ pbl_loader_read_t
| typedef int(* pbl_loader_read_t) (void *ctx, size_t offset, void *buf, size_t len) |
Read bytes from an image source.
- Parameters
-
| ctx | Source context. |
| offset | Offset in the source. |
| [out] | buf | Destination buffer. |
| len | Number of bytes to read. |
- Returns
- 0 if exactly
len bytes were read, a negative errno otherwise.
◆ pbl_loader_copy()
Copy the file part of an image and zero-fill the rest of its memory.
- Parameters
-
| img | Image layout. |
| src | Image source. |
| dst | Destination buffer. |
| dst_size | Size of dst. |
- Return values
-
| 0 | Success. |
| -EINVAL | The layout is inconsistent. |
| -ENOMEM | The image does not fit in dst. |
- Returns
- Other negative errno values from the source.
◆ pbl_loader_relocate()
Apply the relocations of an image copied by pbl_loader_copy().
The part of dst past the file part is used to read the relocation table, and is zeroed again afterwards, so dst_size must hold the file part plus the table.
- Parameters
-
| img | Image layout. |
| src | Image source. |
| dst | Destination buffer. |
| dst_size | Size of dst. |
| address | Address translation, or nullptr to relocate to dst itself. |
| ctx | Context passed to address. |
- Return values
-
| 0 | Success. |
| -EINVAL | The layout is inconsistent, or an entry or slot points outside the image. |
| -ENOMEM | The relocation table does not fit in dst. |
- Returns
- Other negative errno values from the source.