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