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 committed Feb 19, 2022
1 parent 1ad2396 commit af178b2
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 @@ -1052,15 +1052,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 af178b2

Please sign in to comment.