This is an archive of the discontinued LLVM Phabricator instance.

[XRay] Make xray_fn_idx entries PC-relative
ClosedPublic

Authored by MaskRay on Jun 11 2023, 4:59 PM.

Details

Summary

As mentioned by commit c5d38924dc6688c15b3fa133abeb3626e8f0767c (Apr 2020),
PC-relative entries avoid dynamic relocations and can therefore make the
section read-only.

This is similar to D78082 and D78590. We cannot commit to support
compiler/runtime built at different versions, so just don't play with versions.

For Mach-O support (incomplete yet), we use non-temporary lxray_fn_idx[0-9]+
symbols. Label differences are represented as a pair of UNSIGNED and SUBTRACTOR
relocations. The SUBTRACTOR external relocation requires r_extern==1 (needs to
reference a symbol table entry) which can be satisfied by lxray_fn_idx[0-9]+.
A lxray_fn_idx[0-9]+ symbol also serves as the atom for this dead-strippable
section (follow-up to commit b9a134aa629de23a1dcf4be32e946e4e308fc64d).

Diff Detail

Event Timeline

MaskRay created this revision.Jun 11 2023, 4:59 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 11 2023, 4:59 PM
MaskRay requested review of this revision.Jun 11 2023, 4:59 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJun 11 2023, 4:59 PM
Herald added subscribers: llvm-commits, Restricted Project. · View Herald Transcript
ilammy added a comment.EditedJun 17 2023, 9:47 PM

xray_fn_idx entries should use PC-relative relocations as well, but I never get around to fix it. I wonder whether the change may make this patch unneeded or we are going to find other Mach-O relocation related issues.

D145850 is isolation fixes the linker issue for me even with -fxray-function-index.


D152661 – this change – applied in isolation still causes the same error:

ld: in section __DATA,xray_instr_map reloc 0: X86_64_RELOC_SUBTRACTOR must have r_extern=1 file '/var/folders/hv/h2_fjzgx1fl2mh85t65xsv6m0000gn/T/main-5630d5.o' for architecture x86_64

with the linker not being able to handle relocations in xray_instr_map specifically.


When if I apply D145850 and then D152661 on top of it, assembly appears to fail:

hello.s:53:8: error: expected relocatable expression
        .quad   (lxray_sleds_end0-lxray_sleds_start0)>>4
                ^

Assembler can't emit a relocation for this expression involving references to local symbols.

EDIT: No idea why it wants it to be relocatable though, since it's effectively a constant. And you can't do relocations with divisions anyway...

EDIT#2: And if I replace it with a literal:

.quad   12

the linker is now offended by xray_instr_idx section:

ld: in section __DATA,xray_fn_idx reloc 0: X86_64_RELOC_SUBTRACTOR must have r_extern=1 file '/var/folders/hv/h2_fjzgx1fl2mh85t65xsv6m0000gn/T/hello-8f349d.o' for architecture x86_64

since it can't find any extern symbol to latch onto for relocations in xray_fn_idx, with all of them referencing local or temporary symbols.

MaskRay added a comment.EditedJun 18 2023, 10:38 AM

xray_fn_idx entries should use PC-relative relocations as well, but I never get around to fix it. I wonder whether the change may make this patch unneeded or we are going to find other Mach-O relocation related issues.

D145850 is isolation fixes the linker issue for me even with -fxray-function-index.


D152661 – this change – applied in isolation still causes the same error:

ld: in section __DATA,xray_instr_map reloc 0: X86_64_RELOC_SUBTRACTOR must have r_extern=1 file '/var/folders/hv/h2_fjzgx1fl2mh85t65xsv6m0000gn/T/main-5630d5.o' for architecture x86_64

with the linker not being able to handle relocations in xray_instr_map specifically.


When if I apply D145850 and then D152661 on top of it, assembly appears to fail:

hello.s:53:8: error: expected relocatable expression
        .quad   (lxray_sleds_end0-lxray_sleds_start0)>>4
                ^

Assembler can't emit a relocation for this expression involving references to local symbols.

EDIT: No idea why it wants it to be relocatable though, since it's effectively a constant. And you can't do relocations with divisions anyway...

EDIT#2: And if I replace it with a literal:

.quad   12

the linker is now offended by xray_instr_idx section:

ld: in section __DATA,xray_fn_idx reloc 0: X86_64_RELOC_SUBTRACTOR must have r_extern=1 file '/var/folders/hv/h2_fjzgx1fl2mh85t65xsv6m0000gn/T/hello-8f349d.o' for architecture x86_64

since it can't find any extern symbol to latch onto for relocations in xray_fn_idx, with all of them referencing local or temporary symbols.

I think we should apply this patch and change D145850 to stick with Lxray_sleds_start0. The error you see is due to NOT using L (private label prefix).

        .section        __DATA,xray_instr_map
lxray_sleds_start0:
        .space  13     # MCFillFragment
lxray_sleds_end0:

        .section        __DATA,xray_fn_idx
        .p2align        4, 0x90
        .quad   (lxray_sleds_end0-lxray_sleds_start0)>>4
.subsections_via_symbols

/tmp/x-5cd5fc.s:15:8: error: expected relocatable expression
 .quad (lxray_sleds_end0-lxray_sleds_start0)>>4

Due to .subsections_via_symbols, non-L symbols are used as atoms to split subsections. ld -dead_strip may discard lxray_sleds_start0's content or lxray_sleds_end0's content independently.
For some reason the assembler decides not to fold the label difference expression.
However, if we replace .space with .byte/.quad/etc, the assembler will fold this label difference. This may look strange, but I'll call it Mach-O's quirk:)


If we stick with .quad (Lxray_sleds_end0-Lxray_sleds_start0)>>4, this expression can be resolved at assembly time, leaving no relocation to the linker:)

MaskRay updated this revision to Diff 532501.Jun 18 2023, 7:18 PM
MaskRay edited the summary of this revision. (Show Details)

rebase
The Mach-O label difference issue has been fixed by my previous commit 507efbcce03d8c2c5dbea3028bc39f02c88fea79

MaskRay updated this revision to Diff 532525.Jun 18 2023, 9:12 PM
MaskRay edited the summary of this revision. (Show Details)

Clarify terminology

MaskRay accepted this revision.Jun 20 2023, 10:17 PM

I'll land this as PC-relative relocations have been agreed on as the future direction, we currently lack review resource in this area, and I am a de-facto maintainer of XRay for many years.

This revision is now accepted and ready to land.Jun 20 2023, 10:17 PM
MaskRay updated this revision to Diff 533131.Jun 20 2023, 10:24 PM
MaskRay edited the summary of this revision. (Show Details)

fix clang/test/CodeGen/xray-function-index.c

Herald added a project: Restricted Project. · View Herald TranscriptJun 20 2023, 10:24 PM

Tested on aarch64-linux-gnu and powerpc64le-linux-gnu.

I'll use createLinkerPrivateSymbol instead of createLinkerPrivateTempSymbol since the symbol is not considered IsTemporary by MC...

This revision was landed with ongoing or failed builds.Jun 20 2023, 10:41 PM
This revision was automatically updated to reflect the committed changes.