The ARM.exidx section contains a table of 8-byte entries with the first word of each entry an offset to the function it describes and the second word instructions for unwinding if an exception is thrown from that function. The SHF_LINK_ORDER processing will order the table in ascending order of the functions described by the exception table entries. As the address range of an exception table entry is terminated by the next table entry, it is possible to merge consecutive table entries that have identical unwind instructions.
For this implementation we define a table entry to be identical if:
- Both entries are the special EXIDX_CANTUNWIND.
- Both entries have the same inline unwind instructions.
We do not attempt to establish if table entries that are references to
.ARM.extab sections are identical.
This implementation works at a granularity of a single .ARM.exidx InputSection. If all entries in the InputSection are identical to the previous table entry we can remove the InputSection. A more sophisticated but more complex implementation would rewrite InputSection contents so that duplicates within a .ARM.exidx InputSection can be merged. The implementation works really well for code compiled with -ffunction-sections and for code such as llvm that is compiled without exceptions (reduces to a single EXIDX_CANTUNWIND). For the real code I've tested it on it seems to be about half as effective as the fine grained approach, reducing the table size to approximately 70% of its original size. The fine grained approach as used by gold and bfd reduces table size to about 55% of its original value. If projects need the find grained approach I can keep working on this.
This is patch 3 of 3 in sequence:
Can you also add -merge-exidx-entries as well and make it the primary option (i.e. add Config->MergeArmExidx instead of NoMergeArmExidx).