This is an archive of the discontinued LLVM Phabricator instance.

[LLD] Allow usage of LLD as a library
ClosedPublic

Authored by aganea on Feb 4 2022, 6:08 PM.

Details

Summary

As discussed in https://github.com/llvm/llvm-project/issues/53475 this patch allows using LLD-as-a-lib. It also lets clients link-in only the drivers that they want (see tests).

This also adds the unittests infra as in the other LLVM projects. Among the test coverage, I've added the original issue from @krzysz00, see this.

Important note: this doesn't allow (yet) linking in parallel. This will come a bit later, in subsequent patches, for COFF at last.

Diff Detail

Event Timeline

aganea created this revision.Feb 4 2022, 6:08 PM
aganea requested review of this revision.Feb 4 2022, 6:08 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 4 2022, 6:08 PM
mstorsjo added inline comments.Feb 6 2022, 1:38 PM
lld/tools/lld/lld.cpp
127

This is the MSVC specific C++ mangling, and doesn't work as such for the non-MSVC version of LLVM_WEAK_SYMBOL here.

thopre added a subscriber: thopre.Feb 9 2022, 10:40 AM

May I ask what the state of this CL is @aganea? I bumped into this and think it is still quite useful so we should still shoot for landing it.

Herald added a project: Restricted Project. · View Herald TranscriptOct 3 2022, 6:24 AM
Herald added a subscriber: StephenFan. · View Herald Transcript
aganea added a comment.Oct 3 2022, 9:53 AM

May I ask what the state of this CL is @aganea? I bumped into this and think it is still quite useful so we should still shoot for landing it.

This was just exploratory. The next thing users would probably want (cargo/rust for ex.) is multi-threaded calls. However the drivers aren't thread-safe currently. Ideally, I wanted to finish that first (and iron our all the perf. regressions due to thread safety that @MaskRay mentioned in the past). But if others feel that we should have library-fication beforehand, I can clean this & add tests and make it ready for review.

(Note: the ELF port is very very far away from supporting multiple concurrent links)

But if others feel that we should have library-fication beforehand, I can clean this & add tests and make it ready for review.

I would prefer that allowing LLD using as lib to come before multi-threaded support. Appreciate the effort If it isn't too much trouble on your end. The use case I'm encountering is to populate a self sustained MLIR static library that incorporate lld (rather than dependent on a system installed lld). It is completely okay to require only single threaded access as adding a mutex in library call is fairly straightforward.

@aganea If you'd be willing to pick this CL again within one/two month-ish timeline, that's great. I can help with testing since I'm a developer from ROCm side. Hopefully we can wrap this whole thing up by the end of this quarter. On the other hand, if this CL may not be your top priority to work on, and just want to let you know that I'd be willing to take over and finish the rest of work of it. But I have close to zero knowledge of the internals of LLD so may need your pointers and code reviews to make sure I'm on the right track.

aganea updated this revision to Diff 486319.Jan 4 2023, 9:42 AM
aganea retitled this revision from WIP: Allow using LLD as a lib to [LLD] Allow usage of LLD as a library.
aganea edited the summary of this revision. (Show Details)
aganea added reviewers: mstorsjo, hans, thieta, jerryyin.
Herald added a project: Restricted Project. · View Herald TranscriptJan 4 2023, 9:42 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
aganea added a comment.Jan 4 2023, 9:44 AM

@aganea If you'd be willing to pick this CL again within one/two month-ish timeline, that's great. I can help with testing since I'm a developer from ROCm side. Hopefully we can wrap this whole thing up by the end of this quarter. On the other hand, if this CL may not be your top priority to work on, and just want to let you know that I'd be willing to take over and finish the rest of work of it. But I have close to zero knowledge of the internals of LLD so may need your pointers and code reviews to make sure I'm on the right track.

Sorry for the delay, please see the updated patch.

aganea updated this revision to Diff 486326.Jan 4 2023, 9:51 AM
aganea marked an inline comment as done.

Fix casing in CMakeLists.txt

lld/tools/lld/lld.cpp
127

Fixed. Using the default OBJ-in-LIB override mechanism now, as described well by Raymond Chen here.

sbc100 added inline comments.Jan 4 2023, 9:59 AM
lld/Common/CMakeLists.txt
30

Can we come up with a better name for this file maybe? That name makes me think its specifically for the library use case but that isn't true.

Also, we don't capitalize lld elsewhere, with in the filenames or directory names.

How about lldMain.cpp, or perhaps we can come up with a name that doesn't start with lld at all?

lld/include/lld/Common/Driver.h
43–44

Why not llvm::ArrayRef<const char *>?

aganea updated this revision to Diff 486638.Jan 5 2023, 11:22 AM
aganea marked 2 inline comments as done.

As suggested by @sbc100

lld/Common/CMakeLists.txt
30

DriversMain.cpp ?

lld/include/lld/Common/Driver.h
43–44

Please see updated diff. We had std::vector just because of how the -flavor flag is treated and then stripped from args. I changed to llvm::ArrayRef as you suggested and added -flavor in all drivers as a shallow flag. If we want to go that route, I could send a separate patch for that change.

Thanks for your work @aganea. I abstain from giving review from lld's implementation side but thing looks good on the ROCm.cpp unit test. (BTW, do you aim to create that unit test as a demo and then to remove it later? Or else i'd expect to see the "Inputs" folder mocked up in certain way.) Although I did notice a fair amount of test breakages on windows. If you are still actively working on it, I'm willing to approve it once you fix the test failures. Also I plan to give this a test by pulling this diff locally assuming the base of this diff wouldn't cause too much conflicts with our tip of clone.

aganea updated this revision to Diff 491544.Jan 23 2023, 4:24 PM

Fix (hopefully) CI build.

@jerryyin The build errors were due to the fact that I only used LLD as stage-0 linker in my previous tests, assuming that its behavior is conformant with other system linkers. It is not, as described in this paragraph. The same holds for both ELF and COFF drivers.

It seems that there's no universal solution for overriding a symbol in a LIB by a symbol in another LIB. MSVC has /alternatename which works, but there's no such thing on ELF side -- weak symbols cannot be overriden by another LIB once they are visible in the module, or at least I don't know how. There's also the --include=symbol for MSVC and --u=symbol for Unix that can solve the issue by pushing the symbol early in the symbol table, but then we have to deal with the mangling and that doesn't sounds fun. In the end, if users want to use a partial set of the LLD drivers, I resorted to simply implementing the missing drivers with the LLD_IMPLEMENT_SHALLOW_DRIVER macro (see ROCm test). If there's a better/simpler solution for a user perspective, let me know and I'll try it.

aganea updated this revision to Diff 491742.Jan 24 2023, 6:09 AM

Add binaries into diff to fix the preflight build.

hmm the buildkite preflight is still broken, it seems Phabricator is stripping out the binary files from the diff.
My local diff is fine:

but after downloading from this page, they are empty:

It seems that there's no universal solution for overriding a symbol in a LIB by a symbol in another LIB...simply implementing the missing drivers with the LLD_IMPLEMENT_SHALLOW_DRIVER macro

Thanks for letting me know, sounds like a fair solution.

lld/Common/DriversMain.cpp
163–172 ↗(On Diff #491742)

I have a naïve question to ask:

  • In my limited knowledge, previously lldELF is dependent on lldCommon target. lld.cpp would compile just fine because its target is an executable.
  • Now, since DriversMain.cpp become part of lldCommon, and in the implementation of DriversMain,cpp, we start to invoke those specific link target, it implicitly requires, for example, lld::elf::link to be available before lldCommon is compiled. In other words, lldCommon is dependent on lldELF.

Did we just have a cyclic dependency here? And if it is, do you need to move the lldMain() and safeLldMain() into their own independent target such that we can avoid the existence of such a cycle in the compilation?

aganea added inline comments.Jan 24 2023, 1:43 PM
lld/Common/DriversMain.cpp
163–172 ↗(On Diff #491742)

The trickery is that we push lldCommon twice on the command-line, once in lldELF (same in all the other drivers), in another time in the final module. I retained the same mechanic for the unittests.

We could have another lib for LLD-as-lib usage, but I thought from the users' perspective it's simpler if we provided a single "common" lib + the specific drivers' libs.

arsenm added a subscriber: arsenm.Jan 24 2023, 2:30 PM
arsenm added inline comments.
lld/CMakeLists.txt
194–199

Feels like this isn't something lld should have to roll its own handling for

lld/Common/DriversMain.cpp
162–172 ↗(On Diff #491742)

Should move to a separate function with a switch/return

aganea updated this revision to Diff 491980.Jan 24 2023, 6:36 PM
aganea marked 3 inline comments as done.

As suggested by @arsenm

jerryyin accepted this revision.Jan 25 2023, 7:15 AM

LGTM with my limited knowledge of lld. Approving it as this is an extremely useful feature to have, and I want it to make progress after almost a year of staging.

lld/Common/DriversMain.cpp
163–172 ↗(On Diff #491742)

Just want to let you know that I made an (very risky attempt) trying to test this patch in our fork, but this errors out unable to build lld. Based on Harbormaster build result, I don't believe this is due to issues from your patch, but rather our lld fork has been a couple of months old. (Refer to https://github.com/ROCmSoftwarePlatform/rocMLIR/commits/test-lld-update, I pulled the last 3 commits in between this period hoping they are enough narrow the gap.) However, ninja lld would yield a number of linker error as below:

ld.lld: error: undefined symbol: lld::elf::link(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, bool, bool)
referenced by DriversMain.cpp:0 (/root/rocMLIR/external/llvm-project/lld/Common/DriversMain.cpp:0)

external/llvm-project/llvm/tools/lld/Common/CMakeFiles/lldCommon.dir/DriversMain.cpp.o:(lld::lldMain(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, bool))

It would take a while for our fork to completely catch up with the tip of upstream, and I'll give this another test after then. In the mean time I will not hold this review up because of it.

This revision is now accepted and ready to land.Jan 25 2023, 7:15 AM

Thanks for reviewing @jerryyin !
Before going further, I'd like an review/approval from the regular lld contributors as well, whenever you got the chance @mstorsjo @MaskRay @hans @thieta

MaskRay added 1 blocking reviewer(s): Restricted Project.Jan 30 2023, 10:24 AM
This revision now requires review to proceed.Jan 30 2023, 10:24 AM

There is a layering issue. lld/Common/DriversMain.cpp references lld::elf::link which is defined in the library lldELF. lldELF depends on lldCommon so lldCommon cannot depend on lldELF.
You shall see a linker error with -DBUILD_SHARED_LIBS=on due to -Wl,-z,defs

MaskRay requested changes to this revision.Jan 30 2023, 10:58 PM
This revision now requires changes to proceed.Jan 30 2023, 10:58 PM
aganea updated this revision to Diff 494949.Feb 5 2023, 2:37 PM

As suggested by @MaskRay. This changes a few things, but it's for the best I think:

  • Fix circular dependency between lldCommon and the lld drivers.
  • Change safeLldMain -> lldMain and make it the only entry point.
  • Pass down drivers symbols from the caller to lldCommon. This also makes it easier to discriminate between what drivers are linked in the PE, and what it isn't available.
  • Remove all drivers' declarations from Drivers.h, the only usage allowed is to just use lldMain().
  • Tested on Linux with -DBUILD_SHARED_LIBS=ON.
MaskRay added inline comments.Feb 9 2023, 3:31 PM
lld/Common/CMakeLists.txt
30

Keep the file list sorted

lld/Common/DriversMain.cpp
1 ↗(On Diff #494949)

DriverMain instead of DriversMain? I wonder whether Dispatcher in the filename can make it clearer. We have many functions/files with main or Main in the names now...

Also, the header needs a fix.

lld/tools/lld/lld.cpp
92

This can call unsafeLldMain instead, then the parameter bool libUsage can be removed. The downside is that unsafeLldMain will be in an include header but that's probably fine (unsure whether moving it into a nested namespace to discourage its use is useful).

Thanks for the patch! I have gone through the code and it looks in a good shape. Left some suggestions.

lld/Common/DriversMain.cpp
60 ↗(On Diff #494949)

Hopefully share with other template instantiations to decrease the executable size.

152 ↗(On Diff #494949)
178 ↗(On Diff #494949)
lld/ELF/Driver.cpp
112
lld/ELF/Options.td
739 ↗(On Diff #494949)

We should avoid ignoring -flavor in all drivers. It's probably not difficult to strip -flavor from the driver dispatcher.

lld/MachO/Driver.cpp
1372
lld/unittests/AsLibAll/AllDrivers.cpp
19

static

lld/unittests/AsLibAll/CMakeLists.txt
2

Add a file-level comment explaining what AsLibAll means.

lld/unittests/AsLibELF/CMakeLists.txt
2

Add a file-level comment explaining what AsLibELF means.

lld/unittests/AsLibELF/ROCm.cpp
9

Add a comment about the purpose.

22

remove braces

29

static

lld/unittests/AsLibELF/SomeDrivers.cpp
13

static

MaskRay added inline comments.Feb 9 2023, 3:43 PM
lld/ELF/Options.td
739 ↗(On Diff #494949)

Note: we can assert that -flavor is a very first option, i.e. lld -xxx -yyy -flavor gnu isn't allowed.
This may simplify striping the -flavor option.

MaskRay added inline comments.Feb 9 2023, 3:45 PM
lld/tools/lld/lld.cpp
71

Latest clang gives warnings in a -DLLD_DEFAULT_LD_LLD_IS_MINGW=on build.

/home/maskray/llvm/lld/tools/lld/lld.cpp:64:21: warning: extra ';' outside of a function is incompatible with C++98 [-Wc++98-compat-extra-semi]
LLD_HAS_DRIVER(coff);
                    ^

The comment around lld/docs/index.rst:35 needs an update. It still suggests lld::elf::link.

aganea updated this revision to Diff 498530.Feb 17 2023, 5:19 PM
aganea marked 19 inline comments as done.

As suggested by @MaskRay

aganea added a comment.EditedFeb 17 2023, 5:19 PM

Thanks for the in-depth review @MaskRay, I appreciate!

lld/Common/DriversMain.cpp
60 ↗(On Diff #494949)

I checked with CruncherSharp, there are already ,256 instances in the PE image.

lld/ELF/Driver.cpp
112

This pattern works only if the symbol is "public", as in, declared in a header that has been seen already by the current TU. Which is not the case here, I've removed declarations for direct drivers calls, only lld::lldMain remains in Drivers.h. Same comment for the other places where this pattern isn't applicable.

lld/MachO/Driver.cpp
1372

It isn't applicable here, since I remove the declarations from Driver.h

lld/tools/lld/lld.cpp
71

Hmm I don't see this with latest patch, would you have a chance to check again if it's still there?

MaskRay added inline comments.Feb 19 2023, 11:17 PM
lld/Common/Args.cpp
95 ↗(On Diff #498530)

This code introduces a new function. We can strip -flavor near whichDriver or its caller to move all -flavor handling to a single place and avoid polluting the common code.

lld/Common/DriverDispatcher.cpp
160

delete blank line

163

d(...) returns a bool, not an int. exitLld(r) passes the bool to CrashRecoveryContext::throwIfCrash (isCrash expects an exit code) which seems incorrect.

lld/unittests/AsLibAll/AllDrivers.cpp
17

warning: extra ';' outside of a function is incompatible with C++98 [-Wc++98-compat-extra-semi]

lld/unittests/AsLibELF/ROCm.cpp
37

warning: extra ';' outside of a function is incompatible with C++98 [-Wc++98-compat-extra-semi]

lld/unittests/AsLibELF/SomeDrivers.cpp
18

warning: extra ';' outside of a function is incompatible with C++98 [-Wc++98-compat-extra-semi]

aganea updated this revision to Diff 498968.Feb 20 2023, 3:07 PM
aganea marked 6 inline comments as done.

As sugested by @MaskRay

lld/Common/DriverDispatcher.cpp
163

Actually the bool to int conversion is correct. The drivers and thus d returns false on error, true on success. We invert the result and that makes r equal 1 on error, and 0 on success, which is the value that will be returned by the application. throwIfCrash will be really useful when getting back from the CrashRecoveryHandler below in lld::lldMain, but on this particular codepath in unsafeLldMain that will never be hit.
I've added an extra comment to clarify. Please let me know if you think more should be done.

MaskRay accepted this revision.Apr 1 2023, 7:36 AM

Looks great!

lld/tools/lld/lld.cpp
71

The warning goes away! Thanks.

This revision is now accepted and ready to land.Apr 1 2023, 7:36 AM

Thank you for the thorough review @MaskRay !

MaskRay added a comment.EditedJun 13 2023, 1:08 PM

This will now need a rebase to fix merge conflicts. This is a very desired improvement:)

A reminder that don't forget to test LLD_DEFAULT_LD_LLD_IS_MINGW

This revision was landed with ongoing or failed builds.Jun 13 2023, 1:23 PM
This revision was automatically updated to reflect the committed changes.

This will now need a rebase to fix merge conflicts. This is a very desired improvement:)

A reminder that don't forget to test LLD_DEFAULT_LD_LLD_IS_MINGW

Ah yes, I did test it in the past, but I'll give it a try again. Thanks for the reminder.

thakis added a subscriber: thakis.Jun 13 2023, 7:36 PM
thakis added inline comments.
lld/test/Unit/lit.site.cfg.py.in
10

Is this read by anything? clang/test/Unit/lit.site.cfg.py doesn't have it for example.

If not: What about the other vars in here? Are they copy-pasta, or are they needed?

Hi, I think we're seeing some test failures due to this patch. Would you mind taking a look, and reverting for now if it will be hard to fix?

Failing Test: LLD-Unit :: AsLibELF/./LLDAsLibELFTests/AsLib/ROCm

bot: https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8778372807208184913/overview

srj added a subscriber: srj.Jun 14 2023, 9:50 AM

Hi, I'm trying to update Halide's usage of this API to work properly, there are a few things that aren't clear to me:

  • It appears that lldMain is now the preferred entry points; I presume that unsafeLldMain and safeLldMain are intended for internal use only?
  • It's not clear to me whether use of CrashRecoveryContext with this API is required or optional. (We previously didn't use it, though we did wrap calls to the old entry point with std::signal() usage to save and restore signal handlers.)
  • It's not clear to me whether we should use exitLld() or not -- in the event of failure, we always previously exited anyway, but it appears that exitLld() always exits with SIGABRT, which would break the existing contract of our tool (which would exit via exit(1)). Does exitLld() do special cleanup (eg, temp file cleanup) that would be missed otherwise?

    Thanks in advance for any guidance you can give here!

Hi. This fails for me locally with:

FAIL: LLD-Unit :: AsLibELF/./LLDAsLibELFTests/0/2 (3 of 2771) 
******************** TEST 'LLD-Unit :: AsLibELF/./LLDAsLibELFTests/0/2' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/usr/local/google/home/leonardchan/llvm-monorepo/llvm-build-3-master-fuchsia-toolchain/tools/lld/unittests/AsLibELF/./LLDAsLibELFTests-LLD-Unit-2079095-0-2.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=2 GTEST_SHARD_INDEX=0 /usr/loca
l/google/home/leonardchan/llvm-monorepo/llvm-build-3-master-fuchsia-toolchain/tools/lld/unittests/AsLibELF/./LLDAsLibELFTests
--

Script:
--
/usr/local/google/home/leonardchan/llvm-monorepo/llvm-build-3-master-fuchsia-toolchain/tools/lld/unittests/AsLibELF/./LLDAsLibELFTests --gtest_filter=AsLib.ROCm
--
ld.lld: error: cannot open lld/unittests/AsLibELF/Inputs/kernel1.o: No such file or directory
Failed to link: lld/unittests/AsLibELF/Inputs/kernel1.o
lld/unittests/AsLibELF/ROCm.cpp:64: Failure
Value of: runLinker("%S/Inputs/kernel1.o")
  Actual: false
Expected: true
ld.lld: error: cannot open lld/unittests/AsLibELF/Inputs/kernel2.o: No such file or directory
Failed to link: lld/unittests/AsLibELF/Inputs/kernel2.o
lld/unittests/AsLibELF/ROCm.cpp:65: Failure
Value of: runLinker("%S/Inputs/kernel2.o")
  Actual: false
Expected: true
ld.lld: error: cannot open lld/unittests/AsLibELF/Inputs/kernel1.o: No such file or directory
Failed to link: lld/unittests/AsLibELF/Inputs/kernel1.o
lld/unittests/AsLibELF/ROCm.cpp:66: Failure
Value of: runLinker("%S/Inputs/kernel1.o")
  Actual: false
Expected: true
ld.lld: error: cannot open lld/unittests/AsLibELF/Inputs/kernel2.o: No such file or directory
Failed to link: lld/unittests/AsLibELF/Inputs/kernel2.o
lld/unittests/AsLibELF/ROCm.cpp:67: Failure
Value of: runLinker("%S/Inputs/kernel2.o")
  Actual: false
Expected: true

lld/unittests/AsLibELF/ROCm.cpp:64
Value of: runLinker("%S/Inputs/kernel1.o")
  Actual: false
Expected: true
lld/unittests/AsLibELF/ROCm.cpp:65
Value of: runLinker("%S/Inputs/kernel2.o")
  Actual: false
Expected: true
lld/unittests/AsLibELF/ROCm.cpp:66
Value of: runLinker("%S/Inputs/kernel1.o")
  Actual: false
Expected: true
lld/unittests/AsLibELF/ROCm.cpp:67
Value of: runLinker("%S/Inputs/kernel2.o")
  Actual: false
Expected: true


********************
********************
Failed Tests (1):
  LLD-Unit :: AsLibELF/./LLDAsLibELFTests/AsLib/ROCm

Looks like lld can't find the object files? Could you send out a fix or revert?

Hello, I’m out this afternoon, is anybody able to disable this test until I can take a look at it please? Otherwise I’ll do it tonight.

aganea updated this revision to Diff 531910.EditedJun 15 2023, 2:36 PM
aganea marked an inline comment as done.

I've reproduced (on Linux) the issue mentioned above. This doesn't happen on Windows/MSVC because __FILE__ (used in the ROCm.cpp test) always expands to absolute paths when building LLVM, since -DLLVM_USE_RELATIVE_PATHS_IN_FILES requires -ffile-prefix-map which is unsupported on MSVC-cl/clang-cl. Instead, I've switched to using an environment variable LLD_SRC_DIR (which stores relative paths where applicable), see changes in ROCm.cpp and lld/test/Unit/lit.cfg.py.

I've also incorporated @thakis 's changes (if you don't mind) to make the lld unittest paths relocatable. You would still need D152885 to make lld/test relocatable.

@MaskRay @thakis Would you mind taking another look please?

lld/test/Unit/lit.site.cfg.py.in
10

Removed. It was remnants from a copy-paste (indeed) from MLIR.

MaskRay added a comment.EditedJun 16 2023, 2:50 PM
arc patch D119049
ninja -C /tmp/Rel check-lld-unit

gives me failures.

% grep LLVM_USE_RELATIVE_PATHS_IN_FILES /tmp/Rel/CMakeCache.txt
LLVM_USE_RELATIVE_PATHS_IN_FILES:BOOL=OFF
--
/tmp/Rel/tools/lld/unittests/AsLibELF/./LLDAsLibELFTests --gtest_filter=AsLib.ROCm
--
ld.lld: error: target emulation unknown: -m or at least one .o file required
Failed to link: /home/maskray/llvm/lld/unittests/AsLibELF/Inputs/kernel1.o
/home/maskray/llvm/lld/unittests/AsLibELF/ROCm.cpp:69: Failure
Value of: runLinker("%S/Inputs/kernel1.o")
  Actual: false
Expected: true
ld.lld: error: target emulation unknown: -m or at least one .o file required
Failed to link: /home/maskray/llvm/lld/unittests/AsLibELF/Inputs/kernel2.o
/home/maskray/llvm/lld/unittests/AsLibELF/ROCm.cpp:70: Failure
Value of: runLinker("%S/Inputs/kernel2.o")
  Actual: false
arc patch D119049
ninja -C /tmp/Rel check-lld-unit

gives me failures.

% grep LLVM_USE_RELATIVE_PATHS_IN_FILES /tmp/Rel/CMakeCache.txt
LLVM_USE_RELATIVE_PATHS_IN_FILES:BOOL=OFF
--
/tmp/Rel/tools/lld/unittests/AsLibELF/./LLDAsLibELFTests --gtest_filter=AsLib.ROCm
--
ld.lld: error: target emulation unknown: -m or at least one .o file required
Failed to link: /home/maskray/llvm/lld/unittests/AsLibELF/Inputs/kernel1.o
/home/maskray/llvm/lld/unittests/AsLibELF/ROCm.cpp:69: Failure
Value of: runLinker("%S/Inputs/kernel1.o")
  Actual: false
Expected: true
ld.lld: error: target emulation unknown: -m or at least one .o file required
Failed to link: /home/maskray/llvm/lld/unittests/AsLibELF/Inputs/kernel2.o
/home/maskray/llvm/lld/unittests/AsLibELF/ROCm.cpp:70: Failure
Value of: runLinker("%S/Inputs/kernel2.o")
  Actual: false

The two binary files (.o) are missing from the patch. Hold on, I will post it again.

aganea updated this revision to Diff 532304.Jun 16 2023, 3:15 PM

With binary files.

With binary files.

I see that

config.environment["LLD_SRC_DIR"] = config.lld_src_dir

sets the correct path, but ninja check-lld-unit still fails due to thisPath.append(getenv("LLD_SRC_DIR")); getting an empty string...

lld/test/Unit/lit.cfg.py
27

Double quotes to be consistent with https://reviews.llvm.org/D150545

MaskRay added a comment.EditedJun 16 2023, 3:33 PM

Perhaps move the unittests part to a separate patch and land the rest?

aganea updated this revision to Diff 532313.Jun 16 2023, 3:43 PM
aganea marked an inline comment as done.

With double quotes in lit.cfg.py

With binary files.

I see that

config.environment["LLD_SRC_DIR"] = config.lld_src_dir

sets the correct path, but ninja check-lld-unit still fails due to thisPath.append(getenv("LLD_SRC_DIR")); getting an empty string...

Can you post your entire cmake command?

MaskRay reopened this revision.Jun 16 2023, 5:50 PM

With binary files.

I see that

config.environment["LLD_SRC_DIR"] = config.lld_src_dir

sets the correct path, but ninja check-lld-unit still fails due to thisPath.append(getenv("LLD_SRC_DIR")); getting an empty string...

Can you post your entire cmake command?

A bit complex and unrelated to the issue...

https://github.com/MaskRay/Config/wiki/LLVM#configuration
configure-llvm preset

I confirm that /tmp/Debug/tools/lld/unittests/AsLibELF/LLDAsLibELFTests does receive LLD_SRC_DIR and kernel1.o can be found.
The problem is that curl -L 'https://reviews.llvm.org/D119049?download=1' doesn't contain kernel1.o or kernel2.o, so others cannot verify.

You may land the patch and disable the unittest if needed...

This revision is now accepted and ready to land.Jun 16 2023, 5:50 PM
This revision was landed with ongoing or failed builds.Jun 19 2023, 4:35 AM
This revision was automatically updated to reflect the committed changes.

Hello @srj ! Sorry for the late answer.

Hi, I'm trying to update Halide's usage of this API to work properly, there are a few things that aren't clear to me:

  • It appears that lldMain is now the preferred entry points; I presume that unsafeLldMain and safeLldMain are intended for internal use only?

Yes.

  • It's not clear to me whether use of CrashRecoveryContext with this API is required or optional. (We previously didn't use it, though we did wrap calls to the old entry point with std::signal() usage to save and restore signal handlers.)

The CrashRecoveryContext is mandatory in this context since lldMain goes through safeLldMain which also happens to clean the context before the function exists (which is not what regular lld.exe does, it simply leaks all buffers for faster exit). My thinking is that lldMain will be used in long-running applications like a daemon. If you have suggestions/improvements for the API, let me know.

  • It's not clear to me whether we should use exitLld() or not -- in the event of failure, we always previously exited anyway, but it appears that exitLld() always exits with SIGABRT, which would break the existing contract of our tool (which would exit via exit(1)). Does exitLld() do special cleanup (eg, temp file cleanup) that would be missed otherwise?

The SIGABRT you're seeing is simply because exitLld() forwards the crash code through this: https://github.com/llvm/llvm-project/blob/main/lld/Common/ErrorHandler.cpp#L100 - you can set r.retCode = 1; in your code before calling exitLld() to avoid this situation.

thakis added inline comments.Jun 20 2023, 10:11 AM
lld/unittests/AsLibELF/ROCm.cpp
33

From what I can tell, this is a reinvention of add_llvm_unittest_with_input_files() which is discouraged because it entangle build and source data. The recommendation is to have a lit test for things that need to read in-tree things. Unit tests shouldn't affect the source directory.