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

    <tr>
        <th>Summary</th>
        <td>
            [lld][coff] undefined symbols from lazy-loaded archives
        </td>
    </tr>

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

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

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

<pre>
    STR:
- Download https://drive.google.com/file/d/1HhG-LO4MU1GGOLstHlFBi7rOrwKfNDbZ/view?usp=sharing
- Unpack the archive and enter the `repro` directory.
- Run `lld-link @response.txt`

Expected result:
- Linkage fails because of a missing file (`-reproduce` didn't store the manifest file, you may want to edit the response file to remove the manifest-related flags, in which case the expected result is a successful link)

Actual result:
```
lld-link: error: undefined symbol: __declspec(dllimport) _wassert
>>> referenced by /tmp/g/third_party/rust/whatsys/c/windows.c:38
>>> libwhatsys-f4cc7b72e53ee839.rlib(db3b6bfb95261072-windows.o):(get_os_release)

lld-link: error: undefined symbol: __declspec(dllimport) wcscpy
>>> referenced by /tmp/g/third_party/rust/lmdb-rkv-sys/lmdb/libraries/liblmdb/mdb.c:4238
>>> liblmdb_sys-564cd906496499b4.rlib(7b4e66c3aa61e8a8-mdb.o):(mdb_fopen)

lld-link: error: undefined symbol: __declspec(dllimport) _aligned_malloc
>>> referenced by /tmp/g/third_party/rust/lmdb-rkv-sys/lmdb/libraries/liblmdb/mdb.c:9324
>>> liblmdb_sys-564cd906496499b4.rlib(7b4e66c3aa61e8a8-mdb.o):(mdb_env_copyfd1)

lld-link: error: undefined symbol: __declspec(dllimport) _aligned_free
>>> referenced by /tmp/g/third_party/rust/lmdb-rkv-sys/lmdb/libraries/liblmdb/mdb.c:9425
>>> liblmdb_sys-564cd906496499b4.rlib(7b4e66c3aa61e8a8-mdb.o):(mdb_env_copyfd1)
```

What happens is that the symbols, by the time `resolveRemainingUndefines` is called, are still undefined, but `isLazy()` is true for them, and `resolveRemainingUndefines` doesn't handle that case.

A crude retry, like the following, works around the issue:
```
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 3ef9fa3f65c6..46307a386328 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2595,6 +2595,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
 
   // Resolve remaining undefined symbols and warn about imported locals.
 ctx.symtab.resolveRemainingUndefines();
+  run();
+ ctx.symtab.resolveRemainingUndefines();
   if (errorCount())
 return;
 
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index bb7583bb9a7d..5301a7af9c92 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -501,6 +501,10 @@ void SymbolTable::resolveRemainingUndefines() {
     // This odd rule is for compatibility with MSVC linker.
     if (name.starts_with("__imp_")) {
       Symbol *imp = find(name.substr(strlen("__imp_")));
+      if (imp && imp->isLazy()) {
+        forceLazy(imp);
+        continue;
+      }
       if (imp && isa<Defined>(imp)) {
         auto *d = cast<Defined>(imp);
 replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
```

But somehow, there is some non-determinism, as when running the command repeatedly, sometimes, it fails with `strdup` marked as undefined symbol.

Cc: @mstorsjo 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV01v4zgS_TXMpSBDpj5sHXxI4nbPYru3gf7YBfZiUGTJ4oQiBZKy4_n1i5KUTpx2T4DdmR3AsCSyWCw-PtZjiRD0wSJuWHHHiu2NGGLr_OZghFV66G5qp86bL18_s-yWpVuW3iawdSdrnFDQxtgH6uA7xnfK6yMuDs4dDC6k6xjfNdog9TC-W_7Svk8-fMo_flu-f__pQ4i_mN2dXvlP_vT35h_b-t-M744aTyzbDaFn2Ta0wmt7eJr0m-2FfIDYIggvW31EEFYB2oh-bGVl6rH3jpUpKO1RRufPi6fhnwdLFsaoxGj7ACxPPYbe2YCL-BhZmU6W0_-7xx5lRAUew2Dii7V_0PZBHBAaoU2AGqUYAoJrQECnQ9D2ALRoYHzNyjQZI1KDxCkqZRlfRQjReRyD7oTVDYYIE1L3cHYDdOIMJ2EjRAeodBwtn6Kd3EcHHjt3vPSSeDSCwm6MOARypy2cWi1bkCJMtni5NNABBIRBSgyhGQwQOoxXL9G4lXEQ5jUWBNn0Gz-fkGXZLaD3ztPLYBU22qKCcO5qZ6htv1coTehRMr5Wxuiudz4yXsH-JEJAH2f_2bvpBx4b9GglKqjPwPgudj3juwO9tdqrfS98PDO-80OIjO9OrYjhHBjfSfrSVrlTWEiW3Wbr176NrmfzpMmlXNUrjkWGuM6qhTe6phjrrC7rpq4KXi7TFU-ePDrCidi_PmDcu7D3aFAEfAXfH4DMSQbZn_9XXEyn6sQ_HJMJHPqkh6698BrD9D63dqoeEcv5VczIak-gFWUuVZWWeVXmVVXnT6Ct6hzLUmZClEtci3VCDp8Bo-GN69H-8VjthaGEpvadMMbJvwK0KuP5nwQa2uNeuv7cqOWfCF3jEf8S4HJe_D-Bu0xh0_-_WhGhFX2PNlB2jPRNmXNCcEyr9XlsibqbdSc4c8TP2AlttT18m1EPlPV1ACmMQUUDhUcIURvzvDOjvyGSHx0-iN_OJB28modGPyA0bpS4bvRg1ZtTKodhUppWWEVyQWsgCVhc5HWQflAkLdGfybfRD5NINM4YdyL15fdwcv4hgPBusGrs1SEM-DMdULppIEkOOoKgPTYk_vefdnRD2NINwS9k30P9877Jj7YKHyHDpmpE1pSFLBeLvMzSlcjWZcbXsEzTMp-PWZIkvzfbHCi_m35vT87ylOUpJLyoCsbvS2D8bn5fw9x5dFqN1wH003BCJLs1Y8tHoS3j61vvxfkzNiy7l86GCLIVHhgneoPwh3DrPR08trqbJob5ATDdqeDztM-k9tNG_3Ckw0iJk_AWRO2GCNN5RgXGSWHCvOUg4-MinLso6sXPyTNRL7v7jhiAH-yV5v_CGwDohi5GY3a6d4ONs8XTeSQmDt4-j3ibUl9GDL6Kmu6c13j1yuAluep6Vayzuq7ESi0WRZYuxUo0laz42-S66vZ3GHbdfqZZkS6fWDa9LtMLlr0YPJHsDchf8AmeqfS11QGcUuAHQ4d4TCvSdb2IutZGxzOcdGzh45d_3sNE48ULL9PeWdHhIkThY9iT9Tgh3-911-8Z59Nuvpof5gUQ8XXXA8u20Girvrsb6hA94-sQvUF71eUPtHwOaXTJS8ZLon7CsncXefRlON9HAi1e4mymScmu-AeQzkZtKdu97mOr7cUSf4wlCJbdb-ckn717nucKQABiiI4AUiM8UoT4k9HfD4fH3giJX2ZhfzL-QKf-b5Omj-PCeRQOGR_pQYjTU12s-JoQ3g0RguuwdScaEFv0I22oDayzicKIvtNWh0mZApxatJQwxkRFUiFd11F68tgjVSZm1BnyQNo5lShxLqZG8rEyDdGroScd64R_QEWOXye9Cx27p6sDHZiOCqvwq4MbtclUlVXiBjfLFS8Knq-W1U27UbJQq6xZrtdVltdNmol8KZdqtcaiELVc3-gNT3meVmmRrnmxrBZLkYo8U6ullMUyL1csT-nUmYUxx27h_OFmlMPNMl1lZXFjRI0mjMU052MG4FRV-w2ZJ_VwCCxPjQ4xPDuIOpqx_ib7YsuKO-mahhXbK7m-8a4DI347J1SBEzhTMRxuBm82lwX5Qcd2qOdSnGabH0nv3a8o6ZI2xk53sTn844b_JwAA__-kr-3g">