<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/202198>202198</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [RISC-V][lld] RISC-V imported variant UND loses metadata against plain provider under ld.lld
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lld
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          XiaobingHou1219
      </td>
    </tr>
</table>

<pre>
    I ran into this while reducing a RISC-V linker testcase. The reproducer is small, and I have been seeing the same result consistently across three reruns.

### Summary
ld.lld links successfully but when the only variant-CC marking for imported symbol `foo` comes from a regular undefined declaration and the provider DSO defines plain `foo`, the final output drops the imported metadata. In shared links, `ld.lld` leaves `.dynsym` entry `foo` as plain `UND`, omits `DT_RISCV_VARIANT_CC`, and still emits `R_RISCV_JUMP_SLOT foo + 0`. In non-PIE executables, `ld.lld` likewise leaves plain undefined `foo`, omits `DT_RISCV_VARIANT_CC`, and still emits `R_RISCV_JUMP_SLOT foo + 0`. GNU ld.bfd preserves `[VARIANT_CC]` on imported undefined `foo` and emits `DT_RISCV_VARIANT_CC` for the same outputs. Provider-variant controls are correct on both linkers.

### Expected behavior
Link valid RISC-V shared objects and non-PIE executables where one regular input object declares undefined function `foo` as `[VARIANT_CC]`, another regular input object calls `foo`, and the actual definition comes from a plain provider DSO where `foo` itself is not marked `[VARIANT_CC]`. A correct final link must preserve the imported symbol's `STO_RISCV_VARIANT_CC` bit and emit `DT_RISCV_VARIANT_CC` because the output still contains `R_RISCV_JUMP_SLOT foo`.

### Environment
- linker route: GNU as 2.45 input, current ld.lld 22.1.0 and GNU ld.bfd 2.45 final links, RV32/RV64 shared and non-PIE executable outputs, with plain-provider DSOs built by both GNU ld.bfd and ld.lld, contrasted against provider-variant controls.
- march: rv32gc and rv64gc
- mabi: ilp32 and lp64
- first failing stage: link
- local stability check: True

### Reduced testcase
These are the reduced input files from the minimized reproducer I used locally:

#### `caller.s`
```asm
.text
.globl caller
.type caller,@function
caller:
  call foo
  ret
```

#### `decl_variant.s`
```asm
.text
.Lkeep:
  ret
.globl foo
.type foo,@function
.variant_cc foo
```

#### `provider_plain.s`
```asm
.text
.globl foo
.type foo,@function
foo:
  ret
```

### Reproduction notes
- Reproduction command from the packaged case directory:
  `powershell -ExecutionPolicy Bypass -File ./case/run.ps1`
- The reduced inputs live under `case/` and the stable witness outputs live under `verify/run1..run3/`.

### What I checked
- Reduced inputs are preserved under case/.
- Stable witness outputs are preserved under verify/run1..run3/.
- The strict recheck says stable normalized run signatures across three runs: True.
- Tracker guidance link: https://llvm.org/docs/HowToSubmitABug.html
- evidence summary: 3 clean reproductions under hunt/verify/lld_riscv_variant_undef_import_loses_metadata_against_plain_provider/run1..run3` are stable: each run reports 24 provider-variant controls as `ok_variant_provider_import_match` and 24 provider-plain rows as `wrong_drop_imported_variant_metadata`. Representative run1 RV64 `rv64_provider_plain_variant_only/out.bfd.shared.bfd.dynsyms.txt` shows imported `foo` as `FUNC GLOBAL DEFAULT [VARIANT_CC] UND`, `out.bfd.shared.bfd.dynamic.txt` contains `RISCV_VARIANT_CC`, and `out.bfd.shared.bfd.relocs.txt` contains `R_RISCV_JUMP_SLOT foo + 0`. The matching `out.bfd.shared.lld.dynsyms.txt` shows plain `FUNC GLOBAL DEFAULT UND foo`, `out.bfd.shared.lld.dynamic.txt` has no `RISCV_VARIANT_CC`, and `out.bfd.shared.lld.relocs.txt` still contains `R_RISCV_JUMP_SLOT foo + 0`. The canonical RV64 repro in `hunt/cases/confirmed/lld_riscv_variant_undef_import_loses_metadata_against_plain_provider` reproduces the same shared and executable contrast using a single regular `decl_variant.o`, a single `caller.o`, and a plain provider DSO `provider.bfd.so`.

### Notes
upstream/llvm-project/lld/test/ELF/riscv-variant-cc.s` covers single-object defined and undefined variant-CC cases, but not the imported-plain-provider path where the only surviving variant mark comes from a regular undefined declaration. Web searches over LLVM GitHub issue queries for `variant_cc`, `STO_RISCV_VARIANT_CC`, `DT_RISCV_VARIANT_CC`, `undefined`, `import`, and `provider` did not find a direct current report; representative search URLs: https://github.com/llvm/llvm-project/issues?q=is%3Aissue+variant_cc+lld and https://github.com/llvm/llvm-project/issues?q=is%3Aissue+DT_RISCV_VARIANT_CC+lld .

Root key: `lld.riscv.variant_cc_undef_import_against_plain_provider_loses_metadata`
Case id: `20260605-lld-riscv-variant-undef-import-plain-provider-loses-metadata`

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0WNty2zgS_Rr6pUssiro4fvCDbEcz3vI4Kd9m31Qg2BSxBgENLnK0X7_VAElRDp1NtmarXIlNgo3TjXP6Amat2CrEy2RxlSxuzph3tTaX_xRMF0Jtf9d-mk8vzgpdHi5vwTAFQjkNrhYW3mohEQyWngu1BQYPt4_XkxeQQr2iAYfWcWYxhaealu2MLj1HA8KCbZiUSX4NTJVwCzXbIxSICiwi2XI1gmUNfWa9dMC1ssI6VE4egHGjrQVXG6QFxiubJtlNkq3af_NZ_IFH3zTMHOJjWaZSlgGdBes5R2srL-UBCu_grUYVttVKHmDPjGDKTa6voWHmlSBV2oBodto4LMEemkJLSJZZpXWyzIDrBi1URjfAwODWS2bAqxIrobCEErlkhjmhVXCZNtoZvRclGrh5_AJxoYWdZEId7VKIaG0lFJOgvdt5B6XROxse93gadKxkjqVwq8DWzGDrKBlIlln0nYBKZHu09CwtD8oeGnqIypnDwBs2APJ8f9MC0Y1w4cubpw0d9cvmZfVwu7p_2lxft0vIN-uElIDd4od27T-e__i6ebz78gSV1pDkV5ARCAKstJp8vf0M-A25d6yQOIJbvOKbsNg5EPEdI3wSsv8P0t_un0GWaVGVsDNo0bSBTBZXA_MLChdodTycEZBhe_wxysC4Xgjx7G0KX1vaTFqOkjac0dICMwhcG4Pc0f6FdnWrxY_08fnbDjlBLLBme6FNXHAn1CvsmRRlJ-mWUrr4F3JnA_qRQyMRGVIQ9hIQihgbv2tVgHYQkcorHlRxQr7xoMZj065GM26fMyntKRM6sTHuPJNRZiJseKLYyKYTRUZfjrCEsygrSl5Ku5AV4oGOAE1h1R9EVC4dAzTeup45p_qN-STJzwP8x6cvo4QohOuJ8wPeFMiZt3GHNmVEphNTmFAfk52wf8AUtRdGqwaVi68mXZo32jtMZqsgD2YhT-eLeCwUf-6NQeWgTb55nk7TyP6BmsInx0AF8T-8zPIkXz-8LOcd-8ZZ1ymDPnoTro5nORmepYXCC-mgOERRDLYmm22SIbQkJWbpRNiWIuV6Tnwnt7SLQ8MMrykAZj_LtzyYNPvlfMuPKwpBC4TczfK45W45795WwlgHFROSyox1bBvCSZHoQ605k_SqEFK4A_Aa-SstejIexw_sgcoyln0Vju-farQYEoWr29KNZSuiSshOEPSyEUo04t9YDkv3LXhLpYXwyEMyW41uTvsny4zWoEktiSQuWGbxh9kmPkkdfmsJlW6lLiTEj7q3hx12T_LrZJ516SK-b990KCAsDTxu_zbo3u38I7yUnjbtMf806rtXxN0AQr9l60-PJjpDf454krbbbjg_fvFToDt-bgLtfzHYPweOHo84-GN48NCyJiRbpR3ajs0nb7huGlJEz7sd469siyUQa6EUlEW1OQwQkNf6DY2tUUqYfA6pQGj1VUvBD3B12DFrYbKm7jRN8nWgf742XqU7O-0BT9q-dKABC1LsMZQnExkcvuwKdijGMem8CafQ2i75vPtuj0ZUh7jnNE2NV7No5oPs-mfNHNxGWWN5jNMJNFJtVz3Kdq8WYJ-LHsfRjX06jjEdxsY6I7gDgwEYWHawnf9Km4bJmB68AhoimPNU20-7c69sl6eOpg3jVDm2XpRMcYypbraC2rkdLadY5Wsp902qzTbJ16XmNsnXv-u3J_3oi0a41ZXfprVrZGcUSQVkzLY9_2wFM-ASmeoTGJHEtu7XXrkkX_dRkLLcGGH5vssAm9CkbGKJ3kht0W66NnvTVocouk2nwdNgEmlMRxiCg4zXIVoGyaaFfP5xeWnbIP3a4-mV3kJqmON1R82hqdjMGP3WGXkzWm03NDZsuo6jt9q5FNoWUiZaVI454jM5A6ECJ8uMStrmNNv0RmhmSvK19o6Kahrrdfg1zhg2dd8cQbU1oerbnvdN3_r5_hp-u_tytbqDm8_r1fPdE7zvr-A4kFB8RrdkjeDdlidNz8ezwLgtg1JzO2rqvwwLpJ9wQlTUvzcu5Qex6eeusVg839_Asbf90OrQ_ZpRw_rLzpOlU-d_soV8FwLOlFaCupfAo6BEiA62CqQURuLmWlXCNFj-XWJcZsfOxR4HqUEzOWgiu84PvI13GfSfPM4x79uDfr7oFh77neHoMTpZDKp2DPkP-u77Y-H0O-sMsqZNjdTh0tQTw5Xka-r0knz9-Y6SZ4hel1QmnIfGALjeo7Et5Ek_lcVRjPAeB7PBDUh7QtfhnoSGn-HoMnnXbu-Yq9vZqb9Nsd7sxZ7i2mU5Gp9-4c4khT-xAIvUaaMF8gLu7l7-gN-E-90XIKz1CH95NIIs6liE-5bqqJcPJqv27ce3Bcky64EdH8UYnOpoSL9SlCFelQhUiL1MPxLFKpDMrgJNB2k3-gnPD3f2-6q4Fa72Rcp1x4Pv6RCiYZPZ-q9kdiNski9mq_Asya8GQcmvaCIj2H_rDmNBjFudUPxBawevGOp0ssxCviHODjrhU9GPq_xdLuibu2tqHkXZWs-zfJkts8VEynJyKo2wxyTu8Y7Lk2B78p3ts_JyVl7MLtgZXk7PP2WfZufZbHlWX5bVYl7m1UV-zmbTxWK5rKplwT5NF5idzxZzdiYuWyTn03xxPl2mVZbnxfziU8XZfMZzlswzbJiQadf8nIWw0mfTi09nkhUobbirzfOg-jxZ3JyZy3A-hd_aZJ5JYZ09GnDCyXC9G69yksVNsqDjoFLa3u709biTJ9WZ4Hx_sXich0_zWWym4gR95o28_F-5lK9bH_eX-X8CAAD___MfYvc">