How to generate assembly from a cross-compiled binary?
Compile command used is:
arm-none-linux-gnueabi-gcc test.c -o test
How can I disassemble the binary test?
I have used:
objdump -d test -m arm
But it says:
test: file format elf32-little
objdump: can't use supplied machine arm
Any help?
GCC generates the assembly already, you only need to tell it not to throw the files away when finished:
arm-none-linux-gnueabi-gcc -save-temps test.c -o test
Note that the generated files will only contain the assembly language of your code and not the stuff that is linked in from the C libraray, e.g. for printf().
To see the full disassembly including library code, you can use arm-none-linux-gnueabi-objdump -d test.
Side note: "test" is a bad example binary name, as there is a binary named test already in /bin/ or /usr/bin/ on any unix or linux system.
Related
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.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am new to Linux. I am trying to compile my c program into an elf file so I can use read elf to find information about the function,etc. Whenever I try to use the readelf with the output file (after compiling my c program), it says it is not an elf file. So how do I compile my C program so it compiles into an elf file. Or maybe I m not understanding? I am using gcc to compile
Here's my command line for compiling:
gcc -Wall main.c a.out
and then readelf -a a
Ok, so I compiled it with gcc -o test -Wall main.c and it compiled with no errors and then did the readelf with : readelf -a test and it still says it's not an elf and when I do file it comes up with: PE32+ executable (console) x86-64, for MS Windows, so whats's going on here?
Let's try it:
gcc -Wall test.c a.out
gcc: error: a.out: No such file or directory
that's a strong hint that something went wrong... So gcc doesn't produce any a.out file (and if the a.out file already exists, passing it like this tells gcc to try to compile it, and since it's not a valid text/c file, you'll get a.out: file not recognized: File truncated and it will end badly as well).
You need to specify the executable output with -o switch (if you need a.out on unix/linux, just don't type it)
gcc -Wall test.c
will create a.out executable (.elf) if no compilation error is found.
gcc -o myexe -Wall test.c
allows to change executable name.
EDIT: you're not running Linux but Cygwin (on Windows). That doesn't make the answer above invalid, but Cygwin is creating native windows executables, not .elf files. You cannot create .elf files using gcc there (unless you get a windows -> Linux cross-compiler if it exists)
readelf command is present in the Cygwin distro, but won't read programs compiled with gcc. It can analyze .elf files from Linux or other systems using that executable format, but certainly not Windows PE format.
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'
I would like to know how to generate assembler code from a C program using Unix.
I tried the gcc: gcc -c file.c
I also used firstly cpp and then try as but I'm getting errors.
I'm trying to build an assembler program from 3 different programs
prog1.c prog2.c prog.h
Is it correct to do gcc -S prog1.c prog2.c prog.h?
Seems that is not correct. I don't know if I have to generate the assembler from each of them and then link them
Thanks
According the manual:
`-S'
Stop after the stage of compilation proper; do not assemble. The
output is in the form of an assembler code file for each
non-assembler input file specified.
By default, the assembler file name for a source file is made by
replacing the suffix `.c', `.i', etc., with `.s'.
Input files that don't require compilation are ignored.
so try gcc -S file.c.
From man gcc:
-S Stop after the stage of compilation proper; do not
assemble. The output is an assembler code file for
each non-assembler input file specified.
By default, GCC makes the assembler file name for a
source file by replacing the suffix `.c', `.i',
etc., with `.s'. Use -o to select another name.
GCC ignores any input files that don't require com-
pilation.
If you're using gcc (as it seems) it's gcc -S.
Don't forget to specify the include paths with -I if needed.
gcc -I ../my_includes -S my_file.c
and you'll get my_file.s with the Assembler instructions.
objdump -d also works very nicely, and will give you the assembly listing for the whole binary (exe or shared lib).
This can be a lot clearer than using the compiler generated asm since calls to functions within the same source file can show up not yet resolved to their final locations.
Build your code with -g and you can also add --line and/or --source to the objdump flags.