When ARM exceptions are used executable sections have an associated .ARM.exidx section containing unwind information for the executable section. The linker combines these .ARM.exidx sections into a single table ordered by the address of the sections they describe. When an exception is thrown the unwinder looks up the unwinding information by binary searching the table. The .ARM.exidx section contains an table of 8-byte entries of theform:
| PREL31 relocation to function start | Unwind instructions |
The range of addresses covered by the table entry is terminated by the next table entry. This allows consecutive table entries that are identical to be merged, leaving a single large range of PC values matching the same set of unwinding information. Unfortunately if an executable section does not have an associated .ARM.exidx section but is placed after an executable section with unwinding information it can "inherit" the unwind information of the previous table entry instead of terminating it. To fix this problem the linker generates an EXIDX_CANTUNWIND entry for all executable sections without .ARM.exidx sections. I've followed the ld.gold high level behaviour here:
- Generate EXIDX_CANTUNWIND sections only when there is a .ARM.exidx OutputSection.
- Only generate EXIDX_CANTUNWIND sections for executable, non-0 sized non-synthetic sections.
- We want consecutive linker generated EXIDX_CANTUNWIND sections to be merged as if they were from InputFiles.
The implementation extends the sentinel section concept to an arbitrary InputSection. This permits the terminating SentinelSection to be merged into a previous EXIDX_CANTUNWIND entry, although I haven't done that in this patch to limit the number of changes.
Fixes pr40277 https://bugs.llvm.org/show_bug.cgi?id=40277 which has been blocking a project from moving to LLD on Arm.