[Previous][Up] | (#fcl-res)

## Format of resources in object files

Introduction

This appendix describes the format in which resources are stored in object files. This doesn't apply to PECOFF file format, where a format already exists and is well described in documentation from Microsoft.

On Microsoft Windows, resources are natively supported by the operating system. On other systems, Free Pascal RTL provides access to resources, which are embedded in the executable file in the format that is here described.

This appendix doesn't describe a particular object file format implementation (e.g. ELF or Mach-O), but the layout of the sections involved in supporting resources: the way these sections are actually laid out on a file are subject to the rules of the hosting object file format.

For external resource file details, see Description of external resource file format

Conventions

In this document, data sizes are specified with pascal-style data types. They are the following:

Name | Meaning
--- | ---
longword | Unsigned 32 bit integer.
ptruint | Unsigned integer of the size of a pointer

Byte order is the one of the target machine.

All data structures in the sections must be aligned on machine boundaries (4 bytes for 32 bit machines, 8 bytes for 64 bit machines).

Note that all pointers must be valid at runtime. This means that relocations must be written to the object file so that the linker can relocate pointers to the addresses they will have at runtime. Note also that pointers to strings are really pointers, and not offsets to the beginning of the string table.

Resource sections

Free Pascal uses two sections to store resource information:

- fpc.resources. This is a data section that contains all required structures. It must be writable.
- fpc.rehandles. This is a bss section whose size must be equal to (total number of resources)*(size of pointer). It must be writable.

The rest of this chapter will describe the contents of fpc.resources section.

Resource section layout

The fpc.resources section consists of these parts:

- The initial header
- The resource tree, in the form of nodes
- The string table, which can be optional
- The resource data

The initial header

The fpc.resources section starts with this header:

Name | Offset | Length | Description
--- | --- | --- | ---
rootptr | 0 | ptruint | Pointer to the root node.
count | 4/8 | longword | Total number of resources.
usedhandles | 8/12 | longword | Used at runtime. Set to zero in object files.
handles | 12/16 | ptruint | Pointer to the first byte of fpc.reshandles section.

The resource tree

Immediately following the initial header, the resource tree comes. It is made up by nodes that represent resource types, names and language ids.

Data is organized so that resource information (type, name and language id) is represented by a tree: root node contains resource types, that in turn contain resource names, which contain language ids, which describe resource data.

Given a node, its sub-nodes are ordered as follows:

- First the "named" nodes (nodes that use a string as identifier) come, then the id ones (nodes that use an integer as identifier).
- Named nodes are alphabetically sorted, in ascending order.
- Id nodes are sorted in ascending order.

In the file, all sub-nodes of a node are written in the order described above. Then, all sub-nodes of the first sub-node are written, and so on.

Example:

There are three resources:

1. a BITMAP resource with name MYBITMAP and language id $0409
2. a BITMAP resource with name 1 and language id 0
3. a resource with type MYTYPE and name 1 and language id 0

Nodes are laid out this way (note that BITMAP resources have type 2):

    root | MYTYPE 2 | 1 | 0 | MYBITMAP 1 | $0409 | 0

That is, types (MYTYPE is a string, so it comes before 2 which is BITMAP), then names for MYTYPE (1), then language id for resource 3 (0), then names for BITMAP (MYBITMAP and 1), then language id for resource 1 ($0409), then language id for resource 2 (0).

Node format

Name | Offset | Length | Description
--- | --- | --- | ---
nameid | 0 | ptruint | name pointer, integer id or language id
ncount | 4/8 | longword | named sub-nodes count
idcountsize | 8/12 | longword | id sub-nodes count or resource size
subptr | 12/16 | ptruint | pointer to first sub-node

If the node is identified by a string, nameid is a pointer to the null-terminated string holding the name. If it is identified by an id, nameid is that id. Language id nodes are always identified by and ID.

ncount is the number of named sub-nodes of this node (nodes that are identified by a string).

idcountsize is the number of id sub-nodes of this node (nodes that are identified by an integer id). For language id nodes, this field holds the size of the resource data.

subptr is an pointer to the first subnode of this node. Note that it allows to access every subnode of this node, since subnodes of a node always come one after the other. For language id nodes, subptr is the pointer to the resource data.

The string table

The string table is used to store strings used for resource types and names. If all resources use integer ids for name and types, it may not be present in the file.

The string table simply contains null-terminated strings, one after the other.

If present, the string table always contains a 0 (zero) at the beginning. This way, the empty string is located at the first byte of the string table.

The resource data

This part of the file contains raw resource data. As written before, all data structures must be aligned on machine boundaries, so if a resource data size is not a multiple of 4 (for 32 bit machines) or 8 (for 64 bit machines), bytes of padding must be inserted after that resource data.

Exported symbols

Object files containing resources must export a pointer to the first byte of fpc.resources section. The name of this symbol is FPC_RESSYMBOL.

Mach-O specific notes

fpc.resources and fpc.reshandles sections are to be contained in a __DATA segment.