xref: /freebsd/contrib/llvm-project/lld/docs/Partitions.rst (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry AndricPartitions
2*0b57cec5SDimitry Andric==========
3*0b57cec5SDimitry Andric
4*0b57cec5SDimitry Andric.. warning::
5*0b57cec5SDimitry Andric
6*0b57cec5SDimitry Andric  This feature is currently experimental, and its interface is subject
7*0b57cec5SDimitry Andric  to change.
8*0b57cec5SDimitry Andric
9*0b57cec5SDimitry AndricLLD's partitioning feature allows a program (which may be an executable
10*0b57cec5SDimitry Andricor a shared library) to be split into multiple pieces, or partitions. A
11*0b57cec5SDimitry Andricpartitioned program consists of a main partition together with a number of
12*0b57cec5SDimitry Andricloadable partitions. The loadable partitions depend on the main partition
13*0b57cec5SDimitry Andricin a similar way to a regular ELF shared object dependency, but unlike a
14*0b57cec5SDimitry Andricshared object, the main partition and the loadable partitions share a virtual
15*0b57cec5SDimitry Andricaddress space at link time, and each loadable partition is assigned a fixed
16*0b57cec5SDimitry Andricoffset from the main partition. This allows the loadable partitions to refer
17*0b57cec5SDimitry Andricto code and data in the main partition directly without the binary size and
18*0b57cec5SDimitry Andricperformance overhead of PLTs, GOTs or symbol table entries.
19*0b57cec5SDimitry Andric
20*0b57cec5SDimitry AndricUsage
21*0b57cec5SDimitry Andric-----
22*0b57cec5SDimitry Andric
23*0b57cec5SDimitry AndricA program that uses the partitioning feature must decide which symbols are
24*0b57cec5SDimitry Andricgoing to be used as the "entry points" for each partition. An entry point
25*0b57cec5SDimitry Andriccould, for example, be the equivalent of the partition's ``main`` function, or
26*0b57cec5SDimitry Andricthere could be a group of functions that expose the functionality implemented
27*0b57cec5SDimitry Andricby the partition. The intent is that in order to use a loadable partition,
28*0b57cec5SDimitry Andricthe program will use ``dlopen``/``dlsym`` or similar functions to dynamically
29*0b57cec5SDimitry Andricload the partition at its assigned address, look up an entry point by name
30*0b57cec5SDimitry Andricand call it. Note, however, that the standard ``dlopen`` function does not
31*0b57cec5SDimitry Andricallow specifying a load address. On Android, the ``android_dlopen_ext``
32*0b57cec5SDimitry Andricfunction may be used together with the ``ANDROID_DLEXT_RESERVED_ADDRESS``
33*0b57cec5SDimitry Andricflag to load a shared object at a specific address.
34*0b57cec5SDimitry Andric
35*0b57cec5SDimitry AndricOnce the entry points have been decided, the translation unit(s)
36*0b57cec5SDimitry Andriccontaining the entry points should be compiled using the Clang compiler flag
37*0b57cec5SDimitry Andric``-fsymbol-partition=<soname>``, where ``<soname>`` is the intended soname
38*0b57cec5SDimitry Andricof the partition. The resulting object files are passed to the linker in
39*0b57cec5SDimitry Andricthe usual way.
40*0b57cec5SDimitry Andric
41*0b57cec5SDimitry AndricThe linker will then use these entry points to automatically split the program
42*0b57cec5SDimitry Andricinto partitions according to which sections of the program are reachable from
43*0b57cec5SDimitry Andricwhich entry points, similarly to how ``--gc-sections`` removes unused parts of
44*0b57cec5SDimitry Andrica program. Any sections that are only reachable from a loadable partition's
45*0b57cec5SDimitry Andricentry point are assigned to that partition, while all other sections are
46*0b57cec5SDimitry Andricassigned to the main partition, including sections only reachable from
47*0b57cec5SDimitry Andricloadable partitions.
48*0b57cec5SDimitry Andric
49*0b57cec5SDimitry AndricThe following diagram illustrates how sections are assigned to partitions. Each
50*0b57cec5SDimitry Andricsection is colored according to its assigned partition.
51*0b57cec5SDimitry Andric
52*0b57cec5SDimitry Andric.. image:: partitions.svg
53*0b57cec5SDimitry Andric
54*0b57cec5SDimitry AndricThe result of linking a program that uses partitions is essentially an
55*0b57cec5SDimitry AndricELF file with all of the partitions concatenated together. This file is
56*0b57cec5SDimitry Andricreferred to as a combined output file. To extract a partition from the
57*0b57cec5SDimitry Andriccombined output file, the ``llvm-objcopy`` tool should be used together
58*0b57cec5SDimitry Andricwith the flag ``--extract-main-partition`` to extract the main partition, or
59*0b57cec5SDimitry Andric``-extract-partition=<soname>`` to extract one of the loadable partitions.
60*0b57cec5SDimitry AndricAn example command sequence is shown below:
61*0b57cec5SDimitry Andric
62*0b57cec5SDimitry Andric.. code-block:: shell
63*0b57cec5SDimitry Andric
64*0b57cec5SDimitry Andric  # Compile the main program.
65*0b57cec5SDimitry Andric  clang -ffunction-sections -fdata-sections -c main.c
66*0b57cec5SDimitry Andric
67*0b57cec5SDimitry Andric  # Compile a feature to be placed in a loadable partition.
68*0b57cec5SDimitry Andric  # Note that this is likely to be a separate build step to the main partition.
69*0b57cec5SDimitry Andric  clang -ffunction-sections -fdata-sections -fsymbol-partition=libfeature.so -c feature.c
70*0b57cec5SDimitry Andric
71*0b57cec5SDimitry Andric  # Link the combined output file.
72*0b57cec5SDimitry Andric  clang main.o feature.o -fuse-ld=lld -shared -o libcombined.so -Wl,-soname,libmain.so -Wl,--gc-sections
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andric  # Extract the partitions.
75*0b57cec5SDimitry Andric  llvm-objcopy libcombined.so libmain.so --extract-main-partition
76*0b57cec5SDimitry Andric  llvm-objcopy libcombined.so libfeature.so --extract-partition=libfeature.so
77*0b57cec5SDimitry Andric
78*0b57cec5SDimitry AndricIn order to allow a program to discover the names of its loadable partitions
79*0b57cec5SDimitry Andricand the locations of their reserved regions, the linker creates a partition
80*0b57cec5SDimitry Andricindex, which is an array of structs with the following definition:
81*0b57cec5SDimitry Andric
82*0b57cec5SDimitry Andric.. code-block:: c
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andric  struct partition_index_entry {
85*0b57cec5SDimitry Andric    int32_t name_offset;
86*0b57cec5SDimitry Andric    int32_t addr_offset;
87*0b57cec5SDimitry Andric    uint32_t size;
88*0b57cec5SDimitry Andric  };
89*0b57cec5SDimitry Andric
90*0b57cec5SDimitry AndricThe ``name_offset`` field is a relative pointer to a null-terminated string
91*0b57cec5SDimitry Andriccontaining the soname of the partition, the ``addr_offset`` field is a
92*0b57cec5SDimitry Andricrelative pointer to its load address and the ``size`` field contains the
93*0b57cec5SDimitry Andricsize of the region reserved for the partition. To derive an absolute pointer
94*0b57cec5SDimitry Andricfrom the relative pointer fields in this data structure, the address of the
95*0b57cec5SDimitry Andricfield should be added to the value stored in the field.
96*0b57cec5SDimitry Andric
97*0b57cec5SDimitry AndricThe program may discover the location of the partition index using the
98*0b57cec5SDimitry Andriclinker-defined symbols ``__part_index_begin`` and ``__part_index_end``.
99*0b57cec5SDimitry Andric
100*0b57cec5SDimitry AndricRestrictions
101*0b57cec5SDimitry Andric------------
102*0b57cec5SDimitry Andric
103*0b57cec5SDimitry AndricThis feature is currently only supported in the ELF linker.
104*0b57cec5SDimitry Andric
105*0b57cec5SDimitry AndricThe partitioning feature may not currently be used together with the
106*0b57cec5SDimitry Andric``SECTIONS`` or ``PHDRS`` linker script features, nor may it be used with the
107*0b57cec5SDimitry Andric``--section-start``, ``-Ttext``, ``-Tdata`` or ``-Tbss`` flags. All of these
108*0b57cec5SDimitry Andricfeatures assume a single set of output sections and/or program headers, which
109*0b57cec5SDimitry Andricmakes their semantics ambiguous in the presence of more than one partition.
110*0b57cec5SDimitry Andric
111*0b57cec5SDimitry AndricThe partitioning feature may not currently be used on the MIPS architecture
112*0b57cec5SDimitry Andricbecause it is unclear whether the MIPS multi-GOT ABI is compatible with
113*0b57cec5SDimitry Andricpartitions.
114*0b57cec5SDimitry Andric
115*0b57cec5SDimitry AndricThe current implementation only supports creating up to 254 partitions due
116*0b57cec5SDimitry Andricto implementation limitations. This limit may be relaxed in the future.
117