This is an archive of the discontinued LLVM Phabricator instance.

Platform qemu-user: Build path to qemu automatically if not specified
ClosedPublic

Authored by ted on Jul 12 2023, 2:09 PM.

Details

Summary

Get the path to qemu in the following order:

  1. From the property platform.plugin.qemu-user.emulator-path
  2. If that property is not set, from PATH, building the name of the qemu binary from the triple in property platform.plugin.qemu-user.architecture
  3. If that property is not set, from PATH, building the name of the qemu binary from the triple in the target

This will allow a user to load a target and run without setting properties,
if qemu is on the PATH and named qemu-<ArchName>

Diff Detail

Event Timeline

ted created this revision.Jul 12 2023, 2:09 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2023, 2:09 PM
ted requested review of this revision.Jul 12 2023, 2:09 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2023, 2:09 PM
ted added a reviewer: labath.Jul 13 2023, 8:15 AM

I am wondering if we actually need the second step (the architecture setting) here. The main reason it exists is the usage in GetSupportedArchitectures (which is called before a target is created) it seems like the value derived from the target should always be more correct. WDYT? What are the values you get in steps 2 and 3 for your use case?

ted added a comment.EditedJul 18 2023, 7:13 AM

I am wondering if we actually need the second step (the architecture setting) here. The main reason it exists is the usage in GetSupportedArchitectures (which is called before a target is created) it seems like the value derived from the target should always be more correct. WDYT? What are the values you get in steps 2 and 3 for your use case?

I don't think we need to specify the architecture, because I think we can always get it from the triple. There might be a case where someone is using a qemu that isn't named the same as the Triple ArchName, but that case could be covered by emulator-path.

In my case, I'm loading a target, then running, letting the platform get ArchName from the target Triple, then turning that into qemu-riscv32 (or riscv64), and launching that from my PATH.

An example (with my experimental RISC-V ABI plugin):

> bin/lldb
(lldb) platform select qemu-user
  Platform: qemu-user
    Triple: x86_64-*-linux-gnu
OS Version: 5.4.0 (5.4.0-136-generic)
  Hostname: 127.0.0.1
WorkingDir: /local/mnt/ted/8.8/riscv
    Kernel: #153~18.04.1-Ubuntu SMP Wed Nov 30 15:47:57 UTC 2022
(lldb) file ~/lldb_test/factrv32
Current executable set to '/usr2/tedwood/lldb_test/factrv32' (riscv32).
(lldb) b main
Breakpoint 1: where = factrv32`main + 28 at factorial.c:32:8, address = 0x000104ea
(lldb) r
Process 1 launched: '/usr2/tedwood/lldb_test/factrv32' (riscv32)
Process 1 stopped
* thread #1, stop reason = breakpoint 1.1
    frame #0: 0x000104ea factrv32`main(argc=1, argv=0x408005a4) at factorial.c:32:8
   29  	  }
   30  	*/
   31  	
-> 32  	  base = 10;
   33  	
   34  	  printf("Factorial of %d is %d\n", base, factorial(base));
   35  	  return 0;
(lldb) target list
Current targets:
* target #0: /usr2/tedwood/lldb_test/factrv32 ( arch=riscv32-*-linux, platform=qemu-user, pid=1, state=stopped )
(lldb)
ted added a comment.EditedJul 18 2023, 12:23 PM

As for the GetSupportedArchitectures case, downstream I left in the code that checks the property, but changed the return {}; to

return {ArchSpec(llvm::Triple("riscv32-unknown-linux")),
        ArchSpec(llvm::Triple("riscv64-unknown-linux"))};

I don't think we want that upstream, but downstream the only time we're targetting riscv linux is when using qemu.

That lets me run lldb, load a riscv file, then run, without setting any properties.

labath accepted this revision.Jul 20 2023, 11:45 PM

I am wondering if we actually need the second step (the architecture setting) here. The main reason it exists is the usage in GetSupportedArchitectures (which is called before a target is created) it seems like the value derived from the target should always be more correct. WDYT? What are the values you get in steps 2 and 3 for your use case?

I don't think we need to specify the architecture, because I think we can always get it from the triple. There might be a case where someone is using a qemu that isn't named the same as the Triple ArchName, but that case could be covered by emulator-path.

Yeah, that's my thinking as well. Given this, I think we should drop the setting part and just go with the target value directly.

As for the GetSupportedArchitectures case, downstream I left in the code that checks the property, but changed the return {}; to

return {ArchSpec(llvm::Triple("riscv32-unknown-linux")),
        ArchSpec(llvm::Triple("riscv64-unknown-linux"))};

I don't think we want that upstream, but downstream the only time we're targetting riscv linux is when using qemu.

That lets me run lldb, load a riscv file, then run, without setting any properties.

FWIW, the way we do that is by putting something along the lines of:

settings set platform.plugin.qemu-user.architecture aarch64
...
platform select qemu-user
platform select host

into our global lldbinit file. This causes lldb's platform selection logic to pick qemu-user (instead of remote-linux) when encountering an aarch64 executable, without needing to change the source code.

This revision is now accepted and ready to land.Jul 20 2023, 11:45 PM
ted added a comment.Aug 1 2023, 7:56 AM

I am wondering if we actually need the second step (the architecture setting) here. The main reason it exists is the usage in GetSupportedArchitectures (which is called before a target is created) it seems like the value derived from the target should always be more correct. WDYT? What are the values you get in steps 2 and 3 for your use case?

I don't think we need to specify the architecture, because I think we can always get it from the triple. There might be a case where someone is using a qemu that isn't named the same as the Triple ArchName, but that case could be covered by emulator-path.

Yeah, that's my thinking as well. Given this, I think we should drop the setting part and just go with the target value directly.

Do you want me to remove the setting entirely?