OAv2 merge: plumbing of generic merge logic during linkage
This patch adds the plumbing for the OAv2 generic merge logic in the
linker. The linker is an "advanced" consumer of OAv2. After parsing,
it deduplicates the attributes, merges them, detects any compatibility
issues, and finally translates them to GNU properties.
This patch only prepares the infrastructure required to support that
processing. All operations described below rely on helpers or stubs,
and their implementation details will be added in the subsequent
patches.
** Intended pipeline
Disclaimer: the description below documents the intended processing
pipeline. This commit only establishes the phases boundaries, and
call sites. The actual logic of each step is implemented in subsequent
patches.
The OAv2 processing pipeline follows a map-reduce pattern. Obviously,
the actual processing in GNU ld is not multi-threaded, and the
operations are not necessarily executed directly one after another.
* Phase 1, map: successive per-file operations applied on the list of
compatible input objects.
1. Parsing of the OAv2 section's data (also used by objcopy).
2. Translation of relevant GNU properties to OAv2. This is required
for the backward-compatibility with input objects only marked
using GNU properties.
3. Sorting of the subsections and object attributes. Further
operations rely on the ordering to perform some optimization in
the processing of the data.
4. Deduplication of subsections and object attributes, and detection
of any conflict between duplicated subsections or tags.
5. Translation of relevant OAv2 to GNU properties for a forward
-compatibility with the GNU properties merge.
6. Marking of unknown subsections to skip them during the merge
(in phase 2), and to prune them before the output object's
serialization (in phase 3).
* Phase 2, reduce: OAv2 in input objects are merged together.
1. Gathering of "frozen" values (=coming from the command-line
arguments) into a virtual read-only list of subsections and
attributes.
2. Merging of OAv2 from an input file and the frozen input.
3. Merging of the results of step 2 together. Since the OAv2 merge
is commutative and associative, it can be implemented as a reduce.
However, GNU ld implements it as an accumulate because it does
not support multithreading.
Notes: the two merge phases also perform a marking of unsupported/
invalid subsections and attributes. This marking can be used for
debugging, and also more practically, to drop unsupported optional
subsections from the output.
* Phase 3, finalization of the output.
1. Pruning of the unknown / unsupported / invalid subsections and
attributes.
2. Serialization of OAv2 data (also used by objcopy).
Notes:
- There is no translation of the merged OAv2 to GNU properties
at this stage, as the GNU properties merge process has already
all the needed information (translated in step 5 of stage 1) to
produce the GNU properties equivalents.
- The GNU properties are currently required as the runtime linker
does not understand OAv2 yet.
- Phase 3 should also include a compatibility check between the
final merge result of the current link unit and input shared
objects. I opted for postponing this compatibility check, and
GNU properties merge will take care of it as it already does.