annotate lld/docs/Partitions.rst @ 150:1d019706d866

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