This is an archive of the discontinued LLVM Phabricator instance.

[JITLink] Process null symbols
ClosedPublic

Authored by jobnoorman on Apr 30 2023, 2:22 AM.

Details

Summary

Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and
use a null symbol as a placeholder. These symbols were not processed
before making it impossible to create edges for them.

This patch tries to detect these null symbols and create absolute
symbols for them. Note that technically, these null symbols are UND in
the ELF file, not ABS, so it might make more consistent to create a new
symbol type for this (local undefined or so). However, since these
symbols are only used as placeholders (i.e., their values are never
used), I don't think it's worth the effort of doing this.

Also note that in the binaries that I have inspected, this null symbol
always has index 0. Could it make sense to add that to the test to avoid
accidentally adding unnecessary symbols? The reason I didn't do this
yet, is that I couldn't find any references in the specs that actually
guarantee this.

Diff Detail

Event Timeline

jobnoorman created this revision.Apr 30 2023, 2:22 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 30 2023, 2:22 AM
jobnoorman requested review of this revision.Apr 30 2023, 2:22 AM
lhames accepted this revision.May 4 2023, 4:13 PM

See naming comment, but otherwise LGTM. Thanks very much @jobnoorman!

llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
552–553

Let's name these __jitlink_ELF_SYM_UND_<st_value> -- it'll make them easy to spot when debugging, and allow us to keep the invariant that all absolute symbols are named (which means that the change to JITLink.cpp would no longer be needed).

Side note: We should probably change Symbol::hasName so that empty symbols still count as valid names, but that's outside the scope of this patch.

This revision is now accepted and ready to land.May 4 2023, 4:13 PM
jobnoorman added inline comments.May 5 2023, 12:39 AM
llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
552–553

Let's name these __jitlink_ELF_SYM_UND_<st_value> -- it'll make them easy to spot when debugging

Should we maybe go for __jitlink_ELF_SYM_UND_<SymIndex> to make sure the name is always unique? st_value will always be 0 in this case.

and allow us to keep the invariant that all absolute symbols are named (which means that the change to JITLink.cpp would no longer be needed).

I might be missing something here but wouldn't this change still be needed? It handles printing edges with targets that are !isDefined() rather than !hasName().

lhames added inline comments.May 8 2023, 10:02 PM
llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
552–553

Should we maybe go for __jitlink_ELF_SYM_UND_<SymIndex> to make sure the name is always unique? st_value will always be 0 in this case.

Yep -- that sounds good to me.

I might be missing something here but wouldn't this change still be needed? It handles printing edges with targets that are !isDefined() rather than !hasName().

If all absolute symbols are named then they're handled under the if (TargetSym.hasName()) condition, and all symbols are either named or have an associated Block (the else case).

jobnoorman added inline comments.May 8 2023, 11:09 PM
llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
552–553

Should we maybe go for __jitlink_ELF_SYM_UND_<SymIndex> to make sure the name is always unique? st_value will always be 0 in this case.

Yep -- that sounds good to me.

Just noticed there's a practical issue here: Symbol stores its name as a StringRef so I don't think there's a safe way to construct a name on the fly.

So I see two options:

  • Call the symbol __jitlink_ELF_SYM_NULL (or something like that) and assert there is only one;
  • Update Symbol to own its name in a std::string.

I might be missing something here but wouldn't this change still be needed? It handles printing edges with targets that are !isDefined() rather than !hasName().

If all absolute symbols are named then they're handled under the if (TargetSym.hasName()) condition, and all symbols are either named or have an associated Block (the else case).

Ah, of course! Will remove these changes in the next update.

  • Rename added symbols to __jitlink_ELF_SYM_UND_<SymIndex>
  • Remove now unnecessary checks in JITLink.cpp
jobnoorman marked 2 inline comments as done.May 15 2023, 3:45 AM
jobnoorman added inline comments.
llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
552–553

Just noticed there's a practical issue here: Symbol stores its name as a StringRef so I don't think there's a safe way to construct a name on the fly.

I figured out we can use LinkGraph::allocateContent for this so all issues should be resolved now. I'll wait for a final LGTM for these last changes before landing this.

lhames accepted this revision.May 15 2023, 11:26 PM

LGTM! Thanks @jobnoorman!

This revision was landed with ongoing or failed builds.May 16 2023, 12:25 AM
This revision was automatically updated to reflect the committed changes.