cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
117 lines
5.3 KiB
ReStructuredText
117 lines
5.3 KiB
ReStructuredText
Partitions
|
|
==========
|
|
|
|
.. warning::
|
|
|
|
This feature is currently experimental, and its interface is subject
|
|
to change.
|
|
|
|
LLD's partitioning feature allows a program (which may be an executable
|
|
or a shared library) to be split into multiple pieces, or partitions. A
|
|
partitioned program consists of a main partition together with a number of
|
|
loadable partitions. The loadable partitions depend on the main partition
|
|
in a similar way to a regular ELF shared object dependency, but unlike a
|
|
shared object, the main partition and the loadable partitions share a virtual
|
|
address space at link time, and each loadable partition is assigned a fixed
|
|
offset from the main partition. This allows the loadable partitions to refer
|
|
to code and data in the main partition directly without the binary size and
|
|
performance overhead of PLTs, GOTs or symbol table entries.
|
|
|
|
Usage
|
|
-----
|
|
|
|
A program that uses the partitioning feature must decide which symbols are
|
|
going to be used as the "entry points" for each partition. An entry point
|
|
could, for example, be the equivalent of the partition's ``main`` function, or
|
|
there could be a group of functions that expose the functionality implemented
|
|
by the partition. The intent is that in order to use a loadable partition,
|
|
the program will use ``dlopen``/``dlsym`` or similar functions to dynamically
|
|
load the partition at its assigned address, look up an entry point by name
|
|
and call it. Note, however, that the standard ``dlopen`` function does not
|
|
allow specifying a load address. On Android, the ``android_dlopen_ext``
|
|
function may be used together with the ``ANDROID_DLEXT_RESERVED_ADDRESS``
|
|
flag to load a shared object at a specific address.
|
|
|
|
Once the entry points have been decided, the translation unit(s)
|
|
containing the entry points should be compiled using the Clang compiler flag
|
|
``-fsymbol-partition=<soname>``, where ``<soname>`` is the intended soname
|
|
of the partition. The resulting object files are passed to the linker in
|
|
the usual way.
|
|
|
|
The linker will then use these entry points to automatically split the program
|
|
into partitions according to which sections of the program are reachable from
|
|
which entry points, similarly to how ``--gc-sections`` removes unused parts of
|
|
a program. Any sections that are only reachable from a loadable partition's
|
|
entry point are assigned to that partition, while all other sections are
|
|
assigned to the main partition, including sections only reachable from
|
|
loadable partitions.
|
|
|
|
The following diagram illustrates how sections are assigned to partitions. Each
|
|
section is colored according to its assigned partition.
|
|
|
|
.. image:: partitions.svg
|
|
|
|
The result of linking a program that uses partitions is essentially an
|
|
ELF file with all of the partitions concatenated together. This file is
|
|
referred to as a combined output file. To extract a partition from the
|
|
combined output file, the ``llvm-objcopy`` tool should be used together
|
|
with the flag ``--extract-main-partition`` to extract the main partition, or
|
|
``-extract-partition=<soname>`` to extract one of the loadable partitions.
|
|
An example command sequence is shown below:
|
|
|
|
.. code-block:: shell
|
|
|
|
# Compile the main program.
|
|
clang -ffunction-sections -fdata-sections -c main.c
|
|
|
|
# Compile a feature to be placed in a loadable partition.
|
|
# Note that this is likely to be a separate build step to the main partition.
|
|
clang -ffunction-sections -fdata-sections -fsymbol-partition=libfeature.so -c feature.c
|
|
|
|
# Link the combined output file.
|
|
clang main.o feature.o -fuse-ld=lld -shared -o libcombined.so -Wl,-soname,libmain.so -Wl,--gc-sections
|
|
|
|
# Extract the partitions.
|
|
llvm-objcopy libcombined.so libmain.so --extract-main-partition
|
|
llvm-objcopy libcombined.so libfeature.so --extract-partition=libfeature.so
|
|
|
|
In order to allow a program to discover the names of its loadable partitions
|
|
and the locations of their reserved regions, the linker creates a partition
|
|
index, which is an array of structs with the following definition:
|
|
|
|
.. code-block:: c
|
|
|
|
struct partition_index_entry {
|
|
int32_t name_offset;
|
|
int32_t addr_offset;
|
|
uint32_t size;
|
|
};
|
|
|
|
The ``name_offset`` field is a relative pointer to a null-terminated string
|
|
containing the soname of the partition, the ``addr_offset`` field is a
|
|
relative pointer to its load address and the ``size`` field contains the
|
|
size of the region reserved for the partition. To derive an absolute pointer
|
|
from the relative pointer fields in this data structure, the address of the
|
|
field should be added to the value stored in the field.
|
|
|
|
The program may discover the location of the partition index using the
|
|
linker-defined symbols ``__part_index_begin`` and ``__part_index_end``.
|
|
|
|
Restrictions
|
|
------------
|
|
|
|
This feature is currently only supported in the ELF linker.
|
|
|
|
The partitioning feature may not currently be used together with the
|
|
``SECTIONS`` or ``PHDRS`` linker script features, nor may it be used with the
|
|
``--section-start``, ``-Ttext``, ``-Tdata`` or ``-Tbss`` flags. All of these
|
|
features assume a single set of output sections and/or program headers, which
|
|
makes their semantics ambiguous in the presence of more than one partition.
|
|
|
|
The partitioning feature may not currently be used on the MIPS architecture
|
|
because it is unclear whether the MIPS multi-GOT ABI is compatible with
|
|
partitions.
|
|
|
|
The current implementation only supports creating up to 254 partitions due
|
|
to implementation limitations. This limit may be relaxed in the future.
|