Replace x86_64-unknown with x86_64-generic, x86_64-pc and x86_64-uefi.
There is already x86_64-unknown-uefi. As for x86_64-pc and x86_64-generic what would be the difference between the two?
generic would be the non-PC, non-UEFI target
But what is the difference between a PC and non-PC target? And how do either compare with the existing x86_64-unknown-none? We need to know what you actually want to see changed and why to be able to do anything with it.
Memory layout and paging differences mainly
So you want a different target with a non-kernel code model? It would have saved time if you were clear upfront. What object file format and calling convention would it use? It can't be a fully generic userspace target as the object file format and calling convention differs between OSes on x86_64. Also I don't think x86_64-pc-none is a good name for the kernel target. "pc" is a value of the vendor field, but there is no vendor in this case.
I feel like I say this a lot, but: The "vendor" field of a GNU-style "canonical system name" is vestigial and the only reason it's not officially deprecated is because everyone involved on the GNU side of things (including me) has no spare cycles to actually make a dang announcement. It's probably going to be necessary to keep it around forever for the sake of the zillions of shell scripts that parse it, but the only thing it should ever be used for anymore is in retrocomputing contexts, to distinguish the variations of m68k-*-sysv*
and the like that have never been distinguished by anything else. In any other situation, one should hardcode it to either "unknown" (preferred) or "pc" (only to match historical practice on x86) on output and ignore it on input. And the flip side of that is, to prevent ambiguity in the various shorthand forms, "unknown" and "pc" need to only appear in the vendor field. x86_64-pc
is therefore an invalid (incomplete) name.
It is also important to understand that canonical system names are supposed to be quite coarse. The "cpu" field specifies the base ISA. The "os" field specifies the base ABI, kernel interface (if any), and executable image format. That's all. A "-uefi" OS value makes sense because the runtime services available in that environment are radically different from either the "roll everything yourself" environment of "-none", or the "full traditional Unix" environment of "-linux", "-foobsd", etc. Differences in "memory layout and paging", however, sound to me like something that can and should be handled with a new -C code-model=
parameter, rather than a whole new system name.
Maybe there's something I don't understand about what you're trying to do. It would help if you could be a whole lot more specific about the distinction you want Rust to make.
(If what you want is code generation for 16-bit x86, that goes in the CPU field: i8086-pc-msdos
for example.)
Why not? A kernel can't rely on any lower layer to provide a "hosted" environment (sure, maybe there's a hypervisor, but that's traditionally treated as part of the ISA), so the appropriate value for the OS field is either none
or one of the pseudo-OS values that only specify the object file format, e.g. elf
. And when the CPU field specifies something in the x86 family, -pc-
in the vendor field means the same thing as -unknown-
for historical reasons (back in the 1990s someone thought it would be less confusing to end users; I wouldn't have agreed but I wasn't involved at the time).
X86-64 (and even more so 32 bit x86) has a lot of different calling conventions. Which one should be used for a none kernel target?
If you are writing kernel drivers for Linux or kernel mode drivers for Windows, the answer is going to be different.
If you are making your own new kernel from scratch, you get to pick of course, you could even invent your own unique snowflake calling convention! (Please don't though.)
The only targets for which rustc uses pc as vendor are Windows targets. Also distinguishing between kernel and non-kernel targets based on the vendor is a terrible idea IMO.
I never said we should do that! I said we should ignore the vendor field, regardless of what it is, and I said that I imagined the operating system field when compiling kernel code should be either none
or something that specifies the object file format but nothing else (e.g. elf
).
I guess I was assuming that whatever calling convention -none
(or -elf
, -pe
, etc) defaults to would be fine. A kernel's internal calling convention only brushes up against third party code in a small number of predictable places that often get written in assembly language anyway; for instance, the calling convention for system calls doesn't have to match the calling convention of either user space or kernel space because there's going to be an assembly shim on both sides of the trap instruction.
I wouldn't object to a new family of special values for the OS field that specified the object file format and the calling convention but nothing else, but obviously that would need to happen in coordination with all the other compilation toolchains.