brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · e911308 Raw
117 lines · plain
1Partitions2==========3 4.. warning::5 6  This feature is currently experimental, and its interface is subject7  to change.8 9LLD's partitioning feature allows a program (which may be an executable10or a shared library) to be split into multiple pieces, or partitions. A11partitioned program consists of a main partition together with a number of12loadable partitions. The loadable partitions depend on the main partition13in a similar way to a regular ELF shared object dependency, but unlike a14shared object, the main partition and the loadable partitions share a virtual15address space at link time, and each loadable partition is assigned a fixed16offset from the main partition. This allows the loadable partitions to refer17to code and data in the main partition directly without the binary size and18performance overhead of PLTs, GOTs or symbol table entries.19 20Usage21-----22 23A program that uses the partitioning feature must decide which symbols are24going to be used as the "entry points" for each partition. An entry point25could, for example, be the equivalent of the partition's ``main`` function, or26there could be a group of functions that expose the functionality implemented27by the partition. The intent is that in order to use a loadable partition,28the program will use ``dlopen``/``dlsym`` or similar functions to dynamically29load the partition at its assigned address, look up an entry point by name30and call it. Note, however, that the standard ``dlopen`` function does not31allow specifying a load address. On Android, the ``android_dlopen_ext``32function may be used together with the ``ANDROID_DLEXT_RESERVED_ADDRESS``33flag to load a shared object at a specific address.34 35Once the entry points have been decided, the translation unit(s)36containing the entry points should be compiled using the Clang compiler flag37``-fsymbol-partition=<soname>``, where ``<soname>`` is the intended soname38of the partition. The resulting object files are passed to the linker in39the usual way.40 41The linker will then use these entry points to automatically split the program42into partitions according to which sections of the program are reachable from43which entry points, similarly to how ``--gc-sections`` removes unused parts of44a program. Any sections that are only reachable from a loadable partition's45entry point are assigned to that partition, while all other sections are46assigned to the main partition, including sections only reachable from47loadable partitions.48 49The following diagram illustrates how sections are assigned to partitions. Each50section is colored according to its assigned partition.51 52.. image:: partitions.svg53 54The result of linking a program that uses partitions is essentially an55ELF file with all of the partitions concatenated together. This file is56referred to as a combined output file. To extract a partition from the57combined output file, the ``llvm-objcopy`` tool should be used together58with the flag ``--extract-main-partition`` to extract the main partition, or59``-extract-partition=<soname>`` to extract one of the loadable partitions.60An example command sequence is shown below:61 62.. code-block:: shell63 64  # Compile the main program.65  clang -ffunction-sections -fdata-sections -c main.c66 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.c70 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-sections73 74  # Extract the partitions.75  llvm-objcopy libcombined.so libmain.so --extract-main-partition76  llvm-objcopy libcombined.so libfeature.so --extract-partition=libfeature.so77 78In order to allow a program to discover the names of its loadable partitions79and the locations of their reserved regions, the linker creates a partition80index, which is an array of structs with the following definition:81 82.. code-block:: c83 84  struct partition_index_entry {85    int32_t name_offset;86    int32_t addr_offset;87    uint32_t size;88  };89 90The ``name_offset`` field is a relative pointer to a null-terminated string91containing the soname of the partition, the ``addr_offset`` field is a92relative pointer to its load address and the ``size`` field contains the93size of the region reserved for the partition. To derive an absolute pointer94from the relative pointer fields in this data structure, the address of the95field should be added to the value stored in the field.96 97The program may discover the location of the partition index using the98linker-defined symbols ``__part_index_begin`` and ``__part_index_end``.99 100Restrictions101------------102 103This feature is currently only supported in the ELF linker.104 105The partitioning feature may not currently be used together with the106``SECTIONS`` or ``PHDRS`` linker script features, nor may it be used with the107``--section-start``, ``-Ttext``, ``-Tdata`` or ``-Tbss`` flags. All of these108features assume a single set of output sections and/or program headers, which109makes their semantics ambiguous in the presence of more than one partition.110 111The partitioning feature may not currently be used on the MIPS architecture112because it is unclear whether the MIPS multi-GOT ABI is compatible with113partitions.114 115The current implementation only supports creating up to 254 partitions due116to implementation limitations. This limit may be relaxed in the future.117