Skip to content

Commit

Permalink
Make sure all the relocations are filled in for partially cloned targ…
Browse files Browse the repository at this point in the history
…et (#44262)

We collect the relocations (i.e. the GOT slots that is used in the code) for each target
in `tgt.relocs`. Needing a relocation, however, does not imply that the function is cloned
for this target within the group (It does mean that at least one target
in the group has it cloned). The previous version would miss the relocation in this case.

This was triggerred with the following cloning situation

    caller: clone_1
    callee: clone_1, clone_1.clone_3

Since caller.clone_1 may call either callee.clone_1 or callee.clone_1.clone_3 a relocation
for callee will be used and is required to be initialized.
In addition to target 1, target 2 (and in fact target 3) within group 1
will also use caller.clone_1. However, since callee isn't cloned for target 2
the previous version wouldn't have saved this slot in the relocation array.
  • Loading branch information
yuyichao authored Feb 25, 2022
1 parent c9cb015 commit 76fc067
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/llvm-multiversioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1037,15 +1037,15 @@ void CloneCtx::emit_metadata()
idxs.push_back(baseidx);
for (uint32_t j = 0; j < nfvars; j++) {
auto base_f = grp->base_func(fvars[j]);
if (shared_relocs.count(j)) {
if (shared_relocs.count(j) || tgt->relocs.count(j)) {
count++;
idxs.push_back(jl_sysimg_tag_mask | j);
auto f = map_get(*tgt->vmap, base_f, base_f);
offsets.push_back(get_ptrdiff32(cast<Function>(f), fbase));
}
else if (auto f = map_get(*tgt->vmap, base_f)) {
count++;
idxs.push_back(tgt->relocs.count(j) ? (jl_sysimg_tag_mask | j) : j);
idxs.push_back(j);
offsets.push_back(get_ptrdiff32(cast<Function>(f), fbase));
}
}
Expand Down

0 comments on commit 76fc067

Please sign in to comment.