Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
rdos wrote:I think Brendans idea might work, but it cannot determine if long mode applications can execute, or the bitness of the kernel. All it does is to detect the current mode. For example in RDOS, it will always indicate "protected mode", because 32-bit applications always run in protected mode (at least until a processor without protected mode support exist).
but, if understand correctly Brendan's idea, a 32 bit application that does SIDT and check the OS's IDT limit will detect 16 byte IDT entries when running on a 64 bit Operating system
rdos wrote:I think Brendans idea might work, but it cannot determine if long mode applications can execute, or the bitness of the kernel. All it does is to detect the current mode. For example in RDOS, it will always indicate "protected mode", because 32-bit applications always run in protected mode (at least until a processor without protected mode support exist).
but, if understand correctly Brendan's idea, a 32 bit application that does SIDT and check the OS's IDT limit will detect 16 byte IDT entries when running on a 64 bit Operating system
Does it make sense ?
It will detect the current mode of the processor since protected mode requires different limit of IDT compared to long mode (provided the full IDT is used). If the OS is a hybrid, it might either use long mode (and thus IDT entries will be 16 bytes) or protected mode (8 bytes). The app will not be able to detect if the OS can switch mode between different applications. Thus if the 32-bit application determines that the current mode is "protected mode", it cannot conclude the OS won't be able to run 64-bit applications.
rdos wrote:It will detect the current mode of the processor since protected mode requires different limit of IDT compared to long mode (provided the full IDT is used). If the OS is a hybrid, it might either use long mode (and thus IDT entries will be 16 bytes) or protected mode (8 bytes). The app will not be able to detect if the OS can switch mode between different applications. Thus if the 32-bit application determines that the current mode is "protected mode", it cannot conclude the OS won't be able to run 64-bit applications.
My (surely too simple ) assumption was that a 64 bit OS's code can not run in a CPU mode other than 64 bit long mode....How can be possible that OS code itself runs in a different CPU mode (64 bit long mode vs (32 bit) protected mode) when switching between applications having different bitness (e.g. switching from an ELF64 to an ELF32 application) ?
cianfa72 wrote:How can be possible that OS code itself runs in a different CPU mode (64 bit long mode vs (32 bit) protected mode) when switching between applications having different bitness (e.g. switching from an ELF64 to an ELF32 application) ?
You can start application in 32-bit compatible mode, and upon IRQ, interrupt, exception or syscall the cpu is put back to 64-bit segment by changing CS/SS.
bluemoon wrote:You can start application in 32-bit compatible mode, and upon IRQ, interrupt, exception or syscall the cpu is put back to 64-bit segment by changing CS/SS.
rdos wrote:
It will detect the current mode of the processor since protected mode requires different limit of IDT compared to long mode (provided the full IDT is used).
So, if understand correctly, even if the 64 bit OS has to run, definitely, in a 64 bit segment, a 32 bit application running in protected mode (e.g. an ELF32 application) when did SIDT it would detect an IDT limit < 2048 byte (assuming a 256-entries IDT)...right
No. What you get from SIDT is the value setup by the kernel. If the kernel is 64-bit it must use the long mode IDT (which has a max size of 8*256=2048(limit=2047), but may be less if the kernel is insane).
cianfa72 wrote:Here do you refer actually to the two possible long mode "sub-modes" ?
Yes, apologies for my lack of clarity here.
As regards detecting support for 64 bit programs in the OS, I think the only definitive way is to ask the operating system directly. In Windows you can call IsWow64Process() from a 32 bit process and it will tell you whether it is running in compatibility mode or not. In linux you could try something like sysconf(_SC_LONG_BIT) or run 'getconf LONG_BIT' to get the bitness of the underlying kernel.
bluemoon wrote:No. What you get from SIDT is the value setup by the kernel. If the kernel is 64-bit it must use the long mode IDT (which has a max size of 8*256=2048(limit=2047), but may be less if the kernel is insane).
Maybe I'm missing some pieces....Previously in this thread has been told long mode IDT entries are 16 byte long each, so the 64 bit kernel setup is 16*256=4096 byte(limit=4095)....or not ? Thanks
bluemoon wrote:No. What you get from SIDT is the value setup by the kernel. If the kernel is 64-bit it must use the long mode IDT (which has a max size of 8*256=2048(limit=2047), but may be less if the kernel is insane).
Maybe I'm missing some pieces....Previously in this thread has been told long mode IDT entries are 16 byte long each, so the 64 bit kernel setup is 16*256=4096 byte(limit=4095)....or not ? Thanks
Oh yes, 16*256, I should have re-check it before clicking submit. thanks for correction.
cianfa72 wrote:My (surely too simple ) assumption was that a 64 bit OS's code can not run in a CPU mode other than 64 bit long mode....How can be possible that OS code itself runs in a different CPU mode (64 bit long mode vs (32 bit) protected mode) when switching between applications having different bitness (e.g. switching from an ELF64 to an ELF32 application) ?
IIRC, rdos has a kernel that bends over backwards to provide back-compatibility for features that aren't present in compatibility mode, so he's made it a hybrid 32/64 bit kernel, with the 32-bit part running in protected mode.
Normally, however, an OS that supports 64-bit code will stay in long mode the entire time, using compatibility sub-mode for 32-bit processes.
linguofreak wrote:
IIRC, rdos has a kernel that bends over backwards to provide back-compatibility for features that aren't present in compatibility mode, so he's made it a hybrid 32/64 bit kernel, with the 32-bit part running in protected mode.
Umm, not really. That wouldn't work well. Rather, the kernel will run in protected mode when the executing process is 32-bit, and in compability-mode when the executing process is 64-bit. That's why IDT will have 8 byte entries for 32-bit programs and 16 byte entries for 64-bit programs.
For my ignorance...How many IDT entries are used, typically, by a 32/64 bit OS (all 256 entries or less)?
linguofreak wrote:Normally, however, an OS that supports 64-bit code will stay in long mode the entire time, using compatibility sub-mode for 32-bit processes.
So, coming back to the original question, in case of "normal" 64 bit OS we can use definitely/safety the Brendan's idea to find out if our application (32 or 64 bit based) is running on a x86-64 system controlled by a 64 bit OS...?
cianfa72 wrote:For my ignorance...How many IDT entries are used, typically, by a 32/64 bit OS (all 256 entries or less)?
linguofreak wrote:Normally, however, an OS that supports 64-bit code will stay in long mode the entire time, using compatibility sub-mode for 32-bit processes.
So, coming back to the original question, in case of "normal" 64 bit OS we can use definitely/safety the Brendan's idea to find out if our application (32 or 64 bit based) is running on a x86-64 system controlled by a 64 bit OS...?
It's not how to solve a problem. You need to define the set for "normal OS", including the versions, then test your (or Brendan's) theory on those OSes to prove or disprove it.
However, once you defined such set of OSes, it's probably an official API on those platforms that check for such problem.
None of these assumptions are valid under my OS, either. When running 32-bit code, the system may switch in and out of long mode at any time depending on which other applications are running. The IDT also only has 96 entries (but that might change later when LAPIC gets implemented).