How do I generate the a.out file format with GCC on x86 architectures?
With NASM I can do this easily with the -f flag, for example:
nasm -f aout start.asm
objdump -a start.o
start.o: file format a.out-i386-linux
start.o
On Linux, compiling .c files produces an ELF object file. How can I produce a.out files with GCC?
To generate the a.out format with gcc, your linker needs to be told to do so. You can do it by passing it flags from gcc thanks to the -Wl flag.
Here is what you would do for the a.out format:
gcc -Wl,--oformat=a.out-i386-linux file.c -o file.out
You can also display all formats supported by typing:
objdump -i
According to the post Re: How can I control the gcc's output format?, you need to build gcc for a different target (i386-aout).
It sounds plausible as a.out has been deprecated for years (10+).
There are two answers to this question. One is that you'll need to compile a fresh GCC with aout as its target; it's not as simple as flipping a command-line switch. The other answer is a question: why do you actually need this? I can't immediately think of a valid reason.
Related
I'm trying to compile assembly files with NASM and C files with GCC and link all object files together. Moreover, I'd like the C preprocessor to process the assembly files as well. This is normally no problem from the command line or a simple makefile, but I've had some trouble in replicating this functionality in CMake.
The exact process, assuming three files (boot.S, kernel.c, link.ld) would look something like this:
gcc -E -P boot.S -D <...> -o boot.s
nasm -f elf32 boot.s -o boot.o
gcc -c kernel.c -o kernel.o -ffreestanding -O2 -Wall -Wextra
Now its time to link. I want to do this like this (maybe with a few extra flags):
gcc -T link.ld -o out.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
The problems with CMake are the following:
Cmake support for NASM is weird at best. When adding .S files as sources to targets they don't get recognized as assembly files and I get hit with 'cannot determine linker language for target'. I have tried adding 's S' to CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS but it still doesn't work unless I manually set the languages with set_source_files_properties(). Moreover, as is pointed out here, CMAKE_ASM_NASM_LINK_EXECUTABLE is broken.
As far as I understand, after compiling source files to objects, CMake attempts to link them automatically. Which linker will it use to link all .o files? Will it use the linker for C? Will it use the linker for NASM? The answer is relevant, because I need to configure it with the flags I mentioned above.
What would an example CMakeLists.txt would look like that replicates the previously mentioned process? Also do I need a create_custom_command() in order to invoke just the preprocessor? Thank you.
I have generated a .elf file by using
riscv64-unknown-elf-gcc -march=rv64imac -mabi=lp64 -Tlinker.ld *.o add.o -o add.elf -static -nostartfiles -lm -lgcc
And now I want to see the stack to check the values assigned to variables used in my add.c. I believe the same can be obtained from a .dasm/.asm file. How can I generate a .asm/.dasm file from an .elf file?
Just as an extension to dratenik's answer.
I am using riscv32-unknown-elf-objdump --disassemble-all NAME.elf > NAME.disasm
This way you don't even have to go over the -S option. And can just disassemble your .elf file.
Again as dratenik noted you need to adjust the prefix of objdump to you toolchain aka. your compiler prefix
You can stop gcc at the assembly stage by adding the -S switch, the file output by -o will then be an asm source file. Or you can let gcc finish and then take the resulting binary apart with objdump -d. Of course you need to run the objdump binary from the same toolchain, not your system one.
I use gcc compiled the hello.c:
dele-MBP:temp ldl$ ls
a.out hello.c
now, when I cat a.out:
$ cat a.out
??????? H__PAGEZERO?__TEXT__text__TEXTP1P?__stubs__TEXT??__stub_helper__TEXT???__cstring__TEXT??__unwind_info__TEXT?H??__DATA__nl_symbol_ptr__DATA__la_symbol_ptr__DATH__LINKEDIT ?"? 0 0h ? 8
P?
/usr/lib/dyldס??;K????t22
?*(?P
8??/usr/lib/libSystem.B.dylib&`)h UH??H?? ?E??}?H?u?H?=5??1ɉE??H?? ]Ð?%?L?yAS?%i?h?????Hello
P44?4
there shows the messy code.
I want to know what type of the a.out? is it assembly language? if is why there have so many ??? or %%%?
There are several intermediate file formats, depending on the compiler system you use. Most systems use the following steps, here shown with GCC as example:
Preprocessed C source (gcc -E test.c -o test.i), but this is before compilation, strictly speaking
Assembly source (gcc -S test.c -o test.s)
Object file containing machine code, not executable because calls to external functions are not resolved (gcc -c test.c -o test.o)
Executable file containing machine code (gcc test.c -o test)
Only the first two steps generate text files that you could read by cat or in a text editor. This is BTW a valuable source for insight. However, you can use objdump to see most informations contained in the other formats. Please read its documentation.
Each step does also all steps before it. So (gcc test.c -o test) generates assembly source and object file in temporary files that are removed automatically. You can watch that process by giving GCC the option -v.
Use gcc --help to see some entry points for further investigations.
There is at lot more to say about this process but it would fill a book.
I am trying to learn the C Calling conventions in assembly language. To do so, I made a simple program using the puts function from the C standard library.
I assembled and linked the program with the following commands :-
nasm -f elf file.asm
gcc -m32 file.asm -o file
The nasm produces the right object file but when running the gcc to link the object files, I am getting error.
Looking at the error I have figured it out that I don't have the 32 bit version of glibc on my system. How can I install it. I already have installed this package installed.
I have 64 bit ubuntu 12.04 as my OS.
EDIT :- I have installed the following packages, but the problem is still not solved :-
1)ia32-libs
2) libc6-i386
This command will install the 32bit glibc libraries on 64 bit Ubuntu:
sudo apt-get install gcc-multilib
This is the proper syntax for linking assembly object code into an executable using gcc:
gcc -m32 objectfile.o -o executablefile
(nasm -felf32 already creates objectfile.o; the .asm file should not appear on GCC's command line. GCC can assemble+link a .S file in one step using GAS syntax, but NASM is a separate package.)
I assembled and linked the program with the following commands :-
nasm -f elf file.asm
gcc -m32 file.asm -o file
This is wrong. Your first nasm command is probably creating a file.o file (and you should check that, e.g. with ls -l file.o). The second gcc command does not do what you wish.
But gcc does not know about *.asm file extensions (it knows about .S for preprocessable GNU assembler syntax, and .s for assembler code, but probably handle unknown extensions like .asm as ELF object files by default, however file.asm is not an ELF object file). You should try linking with
gcc -Wall -v -m32 file.o -o file
Notice that you give to GCC an object file in ELF (for the linker invoked by gcc) which you previously produced with nasm.
(you might later remove the -v option to gcc)
Alternatively, use the GNU as assembler syntax (not the nasm one), name your file file.S (if you want it to be preprocessed) or file.s (without preprocessing) and use gcc -v -Wall -m32 file.s -o myprog to compile it.
BTW, to understand more about calling conventions, read the x86-64 ABI spec (and the similar one for 32 bits x86 ...), make a small C example file some-example.c, then run gcc -S -fverbose-asm -O some-example.c and look into the produced some-example.s with an editor or pager.
Learn also more about ELF then use readelf (& objdump) appropriately.
You want to install a package called 'ia32-libs'
My file is bootpack.c and it has a function void f() { while(1); } in it.
I want to generate it directly to excutable machine code. So I compile it like this:
gcc -c -nostdinc -fno-builtin bootpack.c
ld -nostdlib file.o -o bootpack.bin
But I find that bootpack.bin is 3.84KB. It is should only be a few bytes, I thought, because it is just a loop. What is wrong? And how to generate this file correctly?
You can use binary as output format for the GNU (BFD-based) linker:
ld -nostdlib file.o --oformat=binary -o bootpack.bin
You can then disassemble that with:
objdump -b binary -m i386 -D bootpack.bin
(substitute your target architecture in place of i386).
Because it contain symbol table information ,to reduce the size of executable you can use strip command .
Use it as "strip --strip-all executable-file-name" so it will remove extra information such as symbol table etc. Even in gcc option -s can be used , there are more option in gcc which can be used .