Skip to content

Commit

Permalink
Make sure all the relocations are filled in for partially cloned target
Browse files Browse the repository at this point in the history
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 and KristofferC committed Feb 25, 2022
1 parent b6ffbeb commit 2d932bb
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 2d932bb

Please sign in to comment.