Is is possible to use %r8d with i686-elf-gcc? - gcc

I'm developing some "fun" labs for a Computer Architecture course that have students write and run a very minimal OS. I'm following the Bare Bones setup from http://wiki.osdev.org/Bare_Bones and using Richard Hull's precompiled i686 cross compiler (https://github.com/rm-hull/barebones-toolchain).
When I try to write assembly code using %r8d, I get this error
Error: bad register name `%r8'
The Readme says "There are two platform flavors, 32- and 64-bit depending on your host linux environment", but also lists "i686 (32-bit ELF)" as one of the targets.
Am I correct that the source of the problem is that the ELF target is 32-bit? If so, is there an easy way to get a cross-compiler with a 64-bit ELF target up and running?

I assume what the README says refers to the "CHOST" of the compiler, while the "CTARGET" is always i686 (which is 32-bit.) There is no %r8d (or %r8, or any %r{number}) register, so no you can't use it (it's an x86-64/IA32-E register.)
You can see my blogpost on CHOST/CBUILD/CTARGET to understand the relationship between the different names of platforms for cross-compiling.

Related

Do I need to recompile for another processor arc?

I try to understand this whole "compiling" topic in a way more detailed than all those "what is a compiler (doing)?" articles out there.
One big question to me is processor- and os-platform dependency when compiling directly to machine code (e.g. C). I try to formulate concrete questions that needs to be resolved in order to get my picture clearer:
I compile my C code via gcc on a Linux distribution... :
Can I run the resulting executable on any other Linux Distribution?
Is that executable bound the processor platform compiled on? Do I need to search for another e.g. power-pc gcc when I am running a x86 distro?
Can I somehow execute this on windows? I know executables differs but the binary code is the same, isn't it?
So in the end my questions aims on: Is compiling about targeting a specifiy OS paltform, processor platform or both?
Thanks!
Compiling targets both, OS, and Architecture.
The OS needs to be targeted because:
The format of what is an "executable" file is different among operating systems.
Programs call the operating system even for common tasks like writing to the console, reading from a file, or terminating cleanly (standards like POSIX mitigate OS dependencies by defining a common layer between the program and the OS).
The CPU architecture must be targeted because the CPU instructions are different, even among different generations of the "same architecture".
Can I run the resulting executable on any other Linux Distribution?
In general, Yes, but on specific cases it may depend on the type of program (f.i. GUI) and the services assumed available on the OS.
Is that executable bound the the processor platform compiled on? Do I need to search for another e.g. power-pc gcc when I am running a x86 distro?
I don't understand what you mean by "search", but, Yes, you can cross-compile from, say, x86 targeting PPC.
Can I somehow execute this on Windows? I know executables differ but the binary code is the same, isn't it?
These days Windows has Ubuntu integration, and that allows for some kind of exceptions, but the general answer is No, because of the above.

cross-compilation terminologies --- build, host and target

I'm seeing a lot of conflict information and would like some clarification.
build, host and target
There are three system names that the build knows about: the machine you are building on (build), the machine that you are building for (host), and the machine that GCC will produce code for (target). When you configure GCC, you specify these with --build=, --host=, and --target=.
Actually, I don't understand what the difference between host and target in the above definition.
Some other page says
‘host’ is the machine (or architecture, or platform) that you are using to compile the code;
‘target’ is the machine (or architecture, or platform) that is intended to run the code.
This makes sense to me, but in this explanation, is the host always the same as the build ?? I'm pretty confused.
In my case, I am configuring such that
the compiler (GCC) runs on x86_64 machine and the binary executable runs on ARM. The program is written in C, so the compiler is GCC.
./configure --build=x86_64 --host=x86_64 --target=arm-linux-gnueabihf
make
make install
It sounds like
build, host are both x86_64 and target is arm. Is that correct?
I am compiling my own embedded program that runs on Jenkins machine (x86_64). And the embedded program runs on ARM based machine.
Lets say I have a PowerPC machine making a compiler that you will use (run) on an x86 machine that will make binaries that run on an ARM.
That makes the PPC the build, the x86 the host, and the target is the ARM. As Basile commented, this is a Canadian-cross.
It's less common to have a build and host that are different, but it certainly does happen. Sometimes the build and host are even the same architecture, but there's something different about the environments that cause this. Making a custom toolchain on my x86 will mean that build and host are x86, but the host may have different libraries, or versions of dependencies, than the build. This is the case when building sand-boxed toolchains for embedded development that run on a build server, for example.
"There are three system names that the build knows about: the machine you are building on (build), the machine that you are building for (host), and the machine that GCC will produce code for (target). When you configure GCC, you specify these with --build=, --host=, and --target="
...
If build, host, and target are all the same, this is called a native.
If build and host are the same but target is different, this is called a cross.
If build, host, and target are all different this is called a canadian (for obscure reasons dealing with Canada’s political party and the background of the person working on the build at that time).
If host and target are the same, but build is different, you are using a cross-compiler to build a native for a different system.
Some people call this a host-x-host, crossed native, or cross-built native.
If build and target are the same, but host is different, you are using a cross compiler to build a cross compiler that produces code for the machine you’re building on.
This is rare, so there is no common way of describing it. There is a proposal to call this a crossback.
Source: https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html
Someone already gave an example of the 'Canadian'.
An example of a cross-compilation is that when building sox from source (the Linux sound library) you need to provide 32-bit binaries for the codecs etc. I just came across this situation on a 64-bit machine, and I want to build it for my own use, which means in this case:
The build is the host (my machine)
The target is a 32-bit system
This is my understanding anyway, I agree this can be a bit confusingly explained, hope this helps :-)

can gcc cross compile for different CPU?

Is it possible for gcc, installed on fedora 16, to cross compile for a different CPU, say SPARC?
I have build a certain understanding, need some expert to correct me if I am wrong. Different operating systems differ by the system calls they use to access the kernel or entirely by the kernel they use. IS THIS CORRECT? different kernels understands different systems calls for accessing underlying hardware. binaries or executables or programs are nothing but a bunch of system calls only. therefore every OS has its own executable. an executable meant to run to on windows wound not run on linux. by cross compiling the source code of any windown's executable we can generate executable for other OSs. word PLATFORM means operating system. POSIX are certain design standards for UNIX-like OSs.
we usually cross compile for different OSs. BUT can we cross compile for different hardware too? for example, in case of a microcontroller which does not have an OS?
No. You can't use native machine (x86) gcc for compiling program files for a different architecture. For that you require a cross-compiler-gcc that is specific to that processor architecture.
Your understanding about system calls for OS is correct. Each OS has its own set of system call which is been used by library. These libraries at the end will be translated into machine language for the processor.
Each Processor Architecture has its own set of instruction know as Instruction Set Architecture(ISA). So when a program written in high-level-language (like C) is compiled, it should be converted into machine language from its ISA. This job is done by the compiler(gcc). A compiler will be specific to only one processor architecture. For example gcc is for x86 processor. So if you want a compiler for different processor in you x86 machine you should go for a cross-compiler of that processor.
You would have to build such a version. That's part of the process of porting gcc to a new platform. You build a version that cross-compiles, then you cross-compile that version, then you test that version on the new platform, debug, rinse, and repeat.

Execute 32 bit object file on 64 bit environment

I made a cross compiling toolchain for arm-gcc, configuring binutils, newlib, gcc and gdb for the arm-elf target. The problem I am having is, when I compile a program with arm-elf-gcc on my Mac, it generates a 32 bit executable with cannot be executed in the 64 bit environment.
What is the easiest way to circumvent this? I could place the 32 bit executables to an arm environment, but I am interested to know if I could execute the file in my Mac in any way?
--Added--
I should have done this before, but let me inform that the target of my program is a Beagleboard, and I was expecting that I would compile and generate the objects using arm-gcc on my Mac OS X and transfer the *.o to the Beagleboard to view output. Alas, it gives the same error on the Beagleboard as well when I do a ./hello.o.
Thanks,
Sayan
There are several issues preventing you from running your executable on a Mac.
1) Architecture. Your Mac is probably an x86/x86_64 machine (or PowerPC) but your binary is compiled for ARM architecture (which is the whole point of using a cross-compiler). These instruction sets are not compatible.
2) Your binary is linked as an ELF object file, whereas Macs use the Mach-O object file format. Your OS cannot load this executable format.
3) Your executable is linked against newlib (for some target which is probably not Mac OS) instead of the Mac OS libc. Your system calls are not correct for this platform.
If your program is a standard unix executable, you may be able to simply compile it with the standard system gcc and it will run. Otherwise, you can run it in an ARM emulator, though this may be pretty complicated to set up.
The fact that it's 32-bit is irrelevant - you can't execute ARM code on a Mac (unless you can find some kind of ARM emulator).

what is cross compilation?

what is cross compilation?
Cross-compilation is the act of compiling code for one computer system (often known as the target) on a different system, called the host.
It's a very useful technique, for instance when the target system is too small to host the compiler and all relevant files.
Common examples include many embedded systems, but also typical game consoles.
A cross-compiler is compiles the source code from one architecture to another architecture.
For example: hello.c
gcc hello.c (gcc is a compiler for x86 architecture.)
arm-cortexa8-linux-gnueabihf-gcc hello.c
(arm-....-gcc is a compiler for the arm architecture.) This you are compiling on the host pc for a target board (e.g rpi, beaglebone, wega board). In this example arm-cortexa8-linux-gnueabihf-gcc is called the 'cross compiler'.
This process is called cross compilation.
see the link for more info cross compilation
To "cross compile" is to compile source on say a Linux box with intent on running it on a MAC or Windows box. This is usually done using a cross compilation plugin, which are readily available from various web servers across the net. If one is to install a cross compilation plugin onto their Linux box that is designed to compile for Windows boxes. Then they may compile for either a Linux/*NIX box as well as have the option to compile and link a Windows-ready executable. This is extremely convenient for a freelance programmer whom has access to no more than a single Linux/Windows/MAC box. Note that various cross compilation plugins will allow for multitudes of applications, some of which you may or may not perceive as useful, thus a thorough perusal of the plugin's README file.
Did you have a particular project in mind that you would like to apply the method of cross compilation to?
In a strict sense, it is the compilation of code on one host that is intended to run on another.
Most commonly it is used with reference to compilation for architectures that are not binary-compatible with the host -- for instance, building RISC binaries on a CISC CPU platform, or 64-bit binaries on a 32-bit system. Or, for example, building firmware intended to run on embedded devices (perhaps using the ARM CPU architecture) on Intel PC-based OSs.
A Cross Compiler is a compiler capable of creating executable code for a platform other than the one on which the compiler is running.
For e.g. a compiler that runs on a Windows 7 PC but generates code that runs on Android smartphone is a cross compiler.
A cross compiler is necessary to compile for multiple platforms from one machine.
A platform could be infeasible for a compiler to run on, such as for the microcontroller of an embedded system because those systems contain no operating system.
In paravirtualization one machine runs many operating systems, and a cross compiler could generate an executable for each of them from one main source.

Resources