What is the difference between vdso32 amd vdsox32? - linux

I apologize if the answer to this question is apparent, but why are there two versions[1] of the vdso for 32-bit executables on linux systems, and what is the criteria used to select among them?
* as can be found in /lib/modules/KERNEL_NAME/vdso

x32 is a Linux ABI which is kind of a mix between x86 and x64. It uses 32-bit address size but runs in full 64-bit mode, including all 64-bit instructions and registers available.

Related

Howto test 32bit kernel specific syscall on a 64bit machine?

My question is quite specific. I have to write a simple program which works with files and should be run on arm 32bit (android). The crucial point is that it MUST use the _llseek syscall. This syscall exists in a 32bit linux kernel but is absent in a 64bit one.
Technically I can write and run this program on the arm device (phone in my case) but I do things on a 64bit box which I would normally use for tests and debugs. In this case my program fails to compile and run on my 64bit box due to the lack of this syscall.
What can be a workaround? I need some friendly test/debug environment. Is installing a 32bit virtual linux the only option?
Thanks in advance, Alex
The -m32 flag worked and indeed the 64bit kernel accepted the bytecode. Stupid enough that I did not come to this simple option myself, thanks.
Or put it differently. I did not notice that the 64bit kernel implements all 32bit calls in parallel, even those absent in the native 64bit code.
You can install an entire Linux 32 bits (x86/32 i.e. ia32) system in a partition -or simply a subdirectory- and run it under chroot in a 64 bits x86-64 Linux kernel (because 64 bits kernels for x86-64 are generally configured to be able to run 32 bits x86 code, that is to execve(2) a 32 bits x86 ELF executable binary) The debootstrap command (on Debian & related) is documenting such a use, see also schroot (you might not need to install every package in 32 bits chroot, only the relevant ones).
You can also use gcc -m32 to compile to a 32 bits x86 ELF binary on a 64 bits x86-64 machine. You may need additional packages (often with multilib or ia32 or x86 in their name).
Of course you need to recompile the application since ARM is not the same as x86/32 bits
However, you cannot run an ARM 32 bits application (only a x86 32 bits one) on a 64 bits x86-64 Linux. To run an ARM application on x86, you need an ARM emulator (e.g. qemu....)
So, debug first your thing on x86/32 bits using a 32 bits chroot-ed environment on your 64 bits x86-64 Linux system.

Determine dynamically linux OS architecture

Is there is a way to know dynamically Linux architecture, whether it x86-64 or x86?
The Posix standard uname function (implemented in the uname(2) syscall) is dynamically giving you the information about the CPU. You probably want the machine field.
Caution about x86-64 kernels running a 32 bit program (e.g. a 32 bits Debian distribution chroot-ed in a 64 bits Debian, or perhaps a 32 bits ELF binary running on a 64 bits system); I have no idea what they give in that situation; I would imagine some x86_64 in that case, since the kernel does not really know about the binaries and libc of the system.
See also the Linux specific personality(2) syscall.
Google is your friend: http://sourceforge.net/p/predef/wiki/Architectures/
You want to test for the macros __amd64__ and __i386__. Ideally, you don't test the macros at all and write correct, portable code.
You can use lscpu command to list characteristics about CPU.

Why does the executable built in 64 bit mode on linux show machine type as AMD x86 64?

I encountered this while trying to understand ELF (Executable and Linking Format).
Steps I followed
Wrote a simple application.
main.c containing
int main(int argc, char **argv){ return 0;}
Compiled in linux environment using gcc. (Done on intel laptop)
Simplest command possible
gcc main.c
Now when I run a.out, it runs without any issue. So build is fine.
I used readelf tool to retrieve the ELF information, where in machine field is put as Advanced Micro Devices X86-64.
This part puzzled me.
So I checked the file header of a.out, it was as per ELF-64 specification (Value 64 - EM_X86_64).
Would anyone care to explain, why does the executable, built in 64 bit mode on linux, show machine type as AMD x86 64?
The x86_64 platform was called the AMD64 platform back when AMD introduced it. Initially, it was far from clear that Intel would ever support it.
You notice how long after i386's ceases to exist, a lot of software had the architecture tag i386? It was because i386 CPUs introduced the instruction set that software uses. Similarly, AMD introduced the instruction set your program uses, so it has an architecture tag that reflects the first CPUs that supported its instruction set. (Modern 32-bit code is still often tagged i686 which refers to the Pentium Pro, circa 1995.)
For a while, the IA-64 (Intel Architecture 64-bit) or Itanium chips were Intel's 64-bit offering, and the Pentium-class chips were the IA-32 chips. The IA-64 chip instruction set was sufficiently different from the Pentium code set that people did not pick it up in large numbers. Meanwhile, AMD came out with a 64-bit extension to the Pentium code set - and that got a lot of support. After a while, Intel bowed to the inevitable and made its own chips that were compatible with the AMD x86/64 chips. But it was AMD that specified the architecture, so it gets the credit in the name.
why does the executable ... show machine type as AMD x86 64?
Because the ELF machine code, used by file, was registered by AMD. There is the official list of registered codes: http://www.sco.com/developers/gabi/latest/ch4.eheader.html (the table at second page):
e_machine
This member's value specifies the required architecture for an individual file.
Name Value Meaning
EM_NONE 0 No machine
...
EM_X86_64 62 AMD x86-64 architecture

Is it possible to execute 32-bit code in 64-bit process by doing mode-switching?

In this page, http://www.x86-64.org/pipermail/discuss/2004-August/005020.html
He said that there is a way to mix 32-bit code and 64-bit code in a application. He assumed the application is 32-bit (in compatibility mode) and then switch to 64-bit mode to execute 64-bit code and vice versa.
Assume my OS is 64-bit linux and my application is 64-bit. I do a far jump to switch to compatibility mode and execute 32-bit code. Does it can work correctly when I do a system call or function call ?
Is there any overhead of mode switching between compatibility mode and 64-bit mode ? I think one of the overhead is I need separate stack for 32-bit and 64-bit.
Could I integrate this idea into JVM, maybe I can dynamic generate 32-bit code in 64-bit JVM, and execute it by mode switching ?
Open-coded syscalls should be fine, since your 32-bit code will use the 32-bit kernel entry point.
Function calls can only be made to other 32-bit code, of course. This includes libc - so your 32-bit code will either have to be self-contained, or you will have to provide thunks for the library functions that it needs. Remember that usually syscalls are not called directly - you normally go via a libc wrapper that will be unavailable to your 32-bit code.
There is certainly an overhead for switching between modes. You should consult your processor documentation to find out what it is.

64-bit linux, Assembly Language, Issues?

I'm currently in the process of learning assembly language.
I'm using Gas on Linux Mint (32-bit). Using this book:
Programming from the Ground Up.
The machine I'm using has an AMD Turion 64 bit processor, but I'm limited to 2 GB of RAM.
I'm thinking of upgrading my Linux installation to the 64-bit version of Linux Mint, but I'm worried that because the book is targeted at 32-bit x86 architecture that the code examples won't work.
So two questions:
Is there likely to be any problems with the code samples?
Has anyone here noticed any benefits in general in using 64-bit Linux over 32-bit (I've seen some threads on Stack Overflow about this but they are mostly related to Windows Vista vs. Windows XP.)
Your code examples should all still work. 64-bit processors and operating systems can still run 32-bit code in a sort of "compatability mode". Your assembly examples are no different. You may have to provide an extra line of assembly or two (such as .BITS 32) but that's all.
In general, using a 64-bit OS will be faster than using a 32-bit OS. x86_64 has more registers than i386. Since you're working on assembly, you already know what registers are used for... Having more of them means less stuff has to be moved on and off the stack (and other temporary memory) thus your program spends less time managing data and more time working on that data.
Edit: To compile 32-bit code on 64-bit linux using gas, you just use the commandline argument "--32", as noted in the GAS manual
Even if you run Linux 64bit, it is possible to compile and run 32bit binaries on it. I don't know how good Mint's support for that is, I assume you should check.
64bit assembler however is not fully compatible to 32bit, for example you have different (more) registers. There are some specific instructions not available on either platform.
I would say the move to 64bit is not a big deal. You can still write 32bit assembly and then perhaps try to get it also running as 64bit (shouldn't be too hard), as a source of even more programming/learning fun.
Usually 32-bits is plenty so only use 64-bits or more if you really NEED IT.
Best to decide prior to programming if you want to do it as a 32-bit app or
a 64-bit app and then stick to it as mixed mode debugging ca get tricky fast.

Resources