How to compile c program into elf format? [closed] - c

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.

Related

Why gcc compiler giving the complied file a new name?

I have reinstalled mingw in my system and downloaded the gcc compiler.
I was shocked after compiling the first file which was "subject.c" but the name of the compiled file which gcc returned was "a.exe". It should be "subject.exe" but do not know why this happened.
Can anyone please explain the reason behind this ?
expected:
gcc subject.c
ls
subject.c subject.exe
tried:
gcc subject.c
ls
subject.c a.exe
-o can be used to give the name of the output file.
For example,
gcc -Wall -Wextra -pedantic subject.c -o subject.exe
(Do enable your compiler's warnings!)
gcc names its output files, in the absence of other instructions, a.out or a.exe depending on system environment because that is what it's supposed to do.
To override this default behavior, you can use the -o flag which tells gcc that the next argument is the desired name for the output file. For instance:
gcc -o subject.exe subject.c
There is no automatic functionality built into gcc to strip a source file of its file extension and add .exe to the end but this can be done manually with Makefiles or other similar scripts, for instance you can write a Makefile with the following contents:
%.exe: %.c
gcc -o $# $<
Then a command like make subject.exe would be translated to gcc -o subject.exe subject.c, which may be what you're looking for.
There is functionality built into gcc to strip source files of their extensions during different parts of the compilation process, which may have been what confused you. For instance a call like gcc -c subject.c can be expected to produce an object file called subject.o, likewise gcc -S subject.c can be expected to produce an assembly language file called subject.s, however this does not apply to executable files not only for historical reasons, but because programs can be compiled from multiple source files and there is not always a clear way to choose a name for the executable output.

What I get after I compile the c file?

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.

cannot specify -o when generating multiple output files [C error]

I have a question about make file using gcc, below is my code in makefile. I got cannot specify -o when generating multiple output files error, but I just cant see where the problem is. Can someone point out my mistakes? Thanks!
BASE_FILES=bwtsearch.c bwtsearch.h bwttext.c bwttext.h chartable.c chartable.h common.h occtable.c occtable.h plset.c plset.h strbuf.c strbuf.h
BASE_ENCODER_FILES=bwtencoder.h bwtencoder.c
BWTSEARCH_FILES=${BASE_FILES} main_bwtsearch.c
BENCODE_FILES=${BASE_ENCODER_FILES} main_bencode.c
PSEARCH_FILES=${BASE_FILES} main_psearch.c
PSEARCH_NL_FILES=${BASE_FILES} main_psearch_nl.c
PENCODE_FILES=${BASE_ENCODER_FILES} main_pencode.c
PENCODE_NL_FILES=${BASE_ENCODER_FILES} main_pencode_nl.c
DEBUG_FILES=${BASE_FILES} main_debug.c
all: bwtsearch psearch psearch_nl pencode pencode_nl bencode
clean:
rm psearch psearch_nl bwtsearch pencode pencode_nl bencode bwt_debug
bwtsearch: ${BWTSEARCH_FILES}
gcc -o bwtsearch ${BWTSEARCH_FILES}
bencode: ${BENCODE_FILES}
gcc -o bencode ${BENCODE_FILES}
psearch: ${PSEARCH_FILES}
gcc -o psearch ${PSEARCH_FILES}
psearch_nl: ${PSEARCH_NL_FILES}
gcc -o psearch_nl ${PSEARCH_NL_FILES}
pencode: ${PENCODE_FILES}
gcc -o pencode ${PENCODE_FILES}
pencode_nl: ${PENCODE_NL_FILES}
gcc -o pencode_nl ${PENCODE_NL_FILES}
debug: ${DEBUG_FILES}
gcc -o bwt_debug ${DEBUG_FILES}
below is the output of the console :)
gcc -o bwtsearch bwtsearch.c bwtsearch.h bwttext.c bwttext.h chartable.c chartable.h common.h occtable.c occtable.h plset.c plset.h strbuf.c strbuf.h main_bwtsearch.c
clang: error: cannot specify -o when generating multiple output files
make: *** [bwtsearch] Error 1
There should be no need to put header files in the list of files to be compiled, since a stylistically correct header file generates no executable code.
It used to be the case that it was mostly harmless to put header files in the gcc command line, because the compiler would add no executable content to the output file as a result of parsing and compiling a header. However, since gcc version 4 or so, and for roughly the same amount of time for clang, header files on the command-line are compiled into precompiled headers for use in later compile steps.
That means that compiling
gcc x.c y.h
will create two products: an executable generated from x.c and a precompiled header generated from y.h.
Gcc (at least up to version 6.3) lets you specify an explicit output filename in this case, although I believe the consequence is that the precompiled header file is written as x and then overwritten by the executable. (It doesn't let you specify an explicit output name in most other cases, such as when you use the -c, -S or -E options to produce an output for every input.) But clang, possibly more sensibly, produces an error when you an explicit output filename with the -o option and you have more than one output, even when that output is a precompiled header (which you possibly didn't intend to produce).
(Confusingly, on Mac OS X, the command gcc normally invokes the clang compiler. I suppose this is to avoid breaking scripts which incorrectly believe that gcc is the generic name for a C compiler.)
The solution is to remove the header files from the list of files to be compiled.

Why only a.out is being created everytime when I make different programs in directory? [duplicate]

This question already has answers here:
Why do some compilers use "a.out" as the default name for executables?
(2 answers)
Closed 6 years ago.
I am learning C in Linux Mint, so I made a directory in which I place my programs. Whenever I compile a program, everytime a.out is being over-written with the new compiled program.
For ex. To compile a hello.c file I run command: cc hello.c, Now this program will create a.out, but I want it to be hello.out
Why is it?
How can I compile so that hello.c should create hello.out file?
Why only a.out is being created everytime when I make different programs in directory?
Because that's the default behavior of your compiler.
How can I compile so that hello.c should create hello.out file?
In general, refer to the documentation for the compiler you're using, which will tell you how to do this.
Assuming you're using gcc or similar, it's the -o option:
gcc hello.c -o hello.out
Default execution in Unix/Linux is a.out file. If you create your own executable then compile program like:
cc hello.c -o hello.out
./hello.out // manually created executable file
or
cc hello.c -o hello
./hello // manually created executable file
Unix/Linux doesn't care about extensions. -o hello basically your suggested name for the executable file that gcc would create.
Why every time a.out is created?
a.out remains the default output file name for executables created by certain compilers/linkers when no output name is specified, even though these executables are no longer in the a.out format.
Please see the wiki page of a.out.
Share your compilation command.
In the compilation command you can mention what the name of the output binary file, like: "gcc hello.c -o hello" then the binary file name will be (hello) because you mention after flag "-o" that you want to name the output file by the name "hello".
If you don't add the flag "-o" with a name, then the default name for the binary file is "a.out".

How to install 32 bit glibc on 64 bit ubuntu

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'

Resources