bash: ./remoteServer .o: cannot execute binary file: Exec format error - c

I am trying to run the c program remoteServer.c. I compiled it using a Makefile. When i try to run it with ./remoteServer.o I get the following error. I read that it could be cause of different architecture but I saw that both were x86-64. I am running ubuntu 18.04.03 on a VM. The code for the make file is after the commands. Also i used chmod 777 on both the .c and .o files.
isidoros#isidoros-VirtualBox:~/choice$ ./remoteServer.o
bash: ./remoteServer.o: cannot execute binary file: Exec format error
isidoros#isidoros-VirtualBox:~/choice$ file remoteServer.c
remoteServer.c: C source, ASCII text
isidoros#isidoros-VirtualBox:~/choice$ file remoteServer.o
remoteServer.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), with debug_info, not stripped
isidoros#isidoros-VirtualBox:~/choice$ uname -m
x86_64
Makefile:
OBJS = remoteServer.o
SOURCE = remoteServer.c
HEADER =
OUT = make
CC = gcc
FLAGS = -g -c -Wall
LFLAGS =
all: $(OBJS)
$(CC) -g $(OBJS) -o $(OUT) $(LFLAGS)
remoteServer.o: remoteServer.c
$(CC) $(FLAGS) remoteServer.c
clean:
rm -f $(OBJS) $(OUT)

Do note that gcc -c compiles source files without linking.
Then, consider that "Compilation refers to the processing of source code files (.c, .cc, or .cpp) and the creation of an 'object' file. This step doesn't create anything the user can actually run. " reference
Meanwhile: "Linking refers to the creation of a single executable file from multiple object files."
So, you probably wanted to link the program, even if it contained a single source file (from your perspective, that might depend on libraries you are including).
I also think that your makefile is trying to name the executable as "make" which might be a problem, since you are probably calling the GNU make program to compile you code.

Related

makefile used compile program in Mac and cross compiler flags it uses in it.what they means & alternative 4 the flags if I am not using cross-compiler

I have a simple OS and Bootloader code downloaded from https://github.com/FRosner/FrOS/tree/minimal-c-kernel
tutorial is at https://dev.to/frosnerd/writing-my-own-boot-loader-3mld
I have some questions about the make file
in below makefile what is x86_64-elf-ld, ld I belive is to link the object files and libraries into output .a and bin files which are libraries. So I believe to output a library called kernel.bin the author used ld's -o flag since its linker then the output is .bin file. I like to know can I output .o file from ld program (by using only ld program can I output .o binary executable, if no, then I assumed its a linker not compiler and compiler can output only executable/or self executable with main() and linker can output only library which needed by some other executable code to call its functions )
the first line is noticed is
kernel.bin: kernel_entry.o kernel.o
x86_64-elf-ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary
since the author built the program in Mac computer and wanted to output binary from code that runs on x86-64 architecture so he needed x86-64 linker which is x86_64-elf-ld and can be easily installed on Mac. But I do not have Mac, I have x86-64 computer then can I use only ld instead of cross platform ld which is x86_64-elf-ld on authors computer also what is -m flag? does -m is an option and elf_i386 is a value of the option -m, can any one please clarify this. or are they (-m and elf_i386 are two separate things if yes then what they mean?) and is with flag -Ttext can I specify the address of output file? so what exactly above two lines means along with there flags
this is next is
kernel_entry.o: kernel_entry.asm
nasm $< -f elf -o $#
what is -f flag and what is elf in above two lines? in above its output-ing .o $# target file which is executable. with NASM assembly compiler
so in rest of the makefile what are -m32,-b,-f,-ffreestanding,-fda flags and what is xxd program?
These are many questions or someone just direct me to some page where I will not like to be lost in dozens of flags. May concise page where these flags can be covered. Or if some one take time to explain them then very thanks
# $# = target file
# $< = first dependency
# $^ = all dependencies
# First rule is the one executed when no parameters are fed to the Makefile
all: run
# Notice how dependencies are built as needed
kernel.bin: kernel_entry.o kernel.o
x86_64-elf-ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary
kernel_entry.o: kernel_entry.asm
nasm $< -f elf -o $#
kernel.o: kernel.c
x86_64-elf-gcc -m32 -ffreestanding -c $< -o $#
# Disassemble
kernel.dis: kernel.bin
ndisasm -b 32 $< > $#
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: mbr.bin kernel.bin
cat $^ > $#
run: os-image.bin
qemu-system-i386 -fda $<
echo: os-image.bin
xxd $<
clean:
$(RM) *.bin *.o *.dis
now the only question I have is why I have to resort to using
x86_64-elf-ld linker and x86_64-elf-gcc compiler since the author used
them because he was not developinh makefile and program on x86-64. But
why I have to use them. So question actually is now: can I use only
gcc instead of x86_64-elf-gcc cross compiler and can I use ld as
linker instead of x86_64-elf-ld cross platform linker.
in short, it is recommended to use a cross compiler when developing an os because it:
allows you to leave the current operating system behind, meaning that
no headers or libraries of your host operating system will be used.
You need a cross-compiler for operating system development, otherwise
a lot of unexpected things can happen because the compiler assumes
that your code is running on your host operating system.
for more information see:
Why do I need a Cross Compiler?
GCC Cross-Compiler
hence, even if you are on x86-64 it is still recommended to use a cross compiler, because it will save you a lot of trouble.
as for the linker, on osdev.org they recommend to:
Linking with your compiler rather than ld
You shouldn't be invoking ld directly. Your cross-compiler is able to
work as a linker and using it as the linker allows it control at the
linking stage. This control includes expanding the -lgcc to the full
path of libgcc that only the compiler knows about. If you get weird
errors during compilation, use your cross-compiler for linking and it
may go away. If you do need ld, be sure to use the cross-linker
(i686-elf-ld) rather than the system linker.
see also: https://wiki.osdev.org/Category:FAQ

ming32-make.exe incorrect parsing of -I and -L flags

I'm on a Windows machine and use MinGW, attempting to compile a hello world program that uses a shared library. After an absurd amount of attempts, I found out the following:
Manually compiling it with gcc and providing -I and -L flags for the required directories works fine.
Using the msys make.exe file provided under the MinGW/msys/1.0/bin installation directory properly executes a Makefile with no problems
Using the mingw32-make.exe provided under MinGW/bin doesn't work properly when trying to build using the same Makefile. From my understanding, it doesn't parse the -I and -L flags at all. It works fine if I add the dependencies (both includes and libs) under their respective MinGW directories.
These past few days while I was trying and familiarizing myself with these tools (I'm comfortable with C's syntax but know about nothing past that) I read many guides and no one seemed to have this issue (from the few that actually attempted this on a Windows machine without using an IDE). Did I miss something? Is my MinGW installation known to have this issue?
Note that at first I was attempting to compile the project using the 64-bit version of the library but failed. I'm guessing this means that I have a 32-bit MinGW installation.
Knowing that some will ask to see the Makefile:
CC = gcc
MY_LIB = -L/e/C_Projects/Libraries/MySharedLib/lib -lMyLibName
MY_INCLUDE = -I/e/C_Projects/Libraries/MySharedLib/include
CFLAGS = -Wall -c $(MY_INCLUDE)
LDFLAGS = -lmingw32 -mwindows $(MY_LIB)
EXE = Test.exe
all: $(EXE)
$(EXE): main.o
$(CC) $< $(LDFLAGS) -o $#
main.o: main.c
$(CC) $(CFLAGS) $< -o $#
clean:
del *.o && del $(EXE)
The error produced by mingw32-make.exe is the following
main.c:1:22: fatal error: MyLib.h: No such file or directory
#include <MyLib.h>
^
compilation terminated.
Makefile:19: recipe for target 'main.o' failed
mingw32-make: *** [main.o] Error 1

How can I compile a header file and a C file together?

I created a file.h and a file.c how can I compile them on Ubuntu?
You only need to compile your .c file(s), not your .h file(s).
To compile file.c on Ubuntu, you can use GCC:
gcc file.c -o my_program
...or Clang:
clang file.c -o my_program
It is possible to precompile your header files, but you only need precompiled headers in particular cases. More information here.
If file.h is not in the same folder as file.c, you can use GCC or Clang's -I option.
Example if file.h is in the include/ folder:
gcc -I include/ file.c -o my_program
In file.c you still have this instruction, with only the filename:
#include "file.h"
You can also use a more generic approach by the usage of a makefile.
Here is a short example of such a file:
# Declaration of variables
CC = gcc
CC_FLAGS = -w -Werror -Wall
# File names
# "prgoram" will be the name of the output produced from the make process
EXEC = program
#Incorporates all the files with .c extension
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
# Main target
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC)
# To obtain object files
%.o: %.c
$(CC) -c $(CC_FLAGS) $< -o $#
# To remove generated files
clean:
rm -f $(EXEC) $(OBJECTS)
To use this utility just make sure that the file itself is within the directory containing your source files and its name is either "makefile" or "Makefile".
To compile the code simply run the following command from your working directory:
make program
This command will automatically link all the source files within your working directory into one executable file with the name of "program". To run the program itself just use the command:
./program
To clean your project and the created executable you can run the command:
make clean
The makefile is very powerful when dealing with larger projects that contain a larger number of source files. Here you can check for more guidance on how to use makefiles. This is also a very detailed tutorial on the topic.
Use following command to compile your program(For GCC Compiler):
gcc file.c -o file
No need to compile file.h file.

Configure automake to target assembly

Is it possible to configure automake to generate a Makefile which, in addition to building the .o files and linked binary, also has targets for %.s? I want to be able to review the compiler output in a text format without having to invoke binutils on the .o files.
Specifically, if I have main.c as a source file, I want to be able to run make main.s. The desired recipe would be the same as that for main.o, but using CC1 := $(CC) -S.
The question is a little XY.
You want to be able make the intermediate assembly file foo.s, where
the source file foo.c is one of the sources in an autotooled project, using
a makefile that is generated by the project's ./configure script. You
assume that to do this you must do something to the automake inputs -
the Makefile.ams? - that will cause ./configure to generate Makefiles
that include assembly targets *.s matching all object targets *.o.
Well you could, but then your project would not be a regular autotooled
project as usually distributed, and there is no need to make it irregular
to get what you want.
The GCC option -save-temps
exists to let developers see the intermediate files of compilation - the preprocessor
output, the assembly.
$ gcc -c -o foo.o foo.c
outputs foo.o
$ gcc -save-temps -c -o foo.o foo.c
outputs:
foo.o
foo.i # preprocessed source
foo.s # assembly
As I expect you know, GNU Make receives compiler options from the make-variable
CFLAGS, and automake respects this convention, independently of and in addition to any compiler
options prescribed by the project's autotooling. So, if you would otherwise generate
makefiles with:
$ ./configure ...
then, to add -save-temps to the C compiler options, generate makefiles instead
with:
$ ./configure CFLAGS=-save-temps ...
And if you are already using CFLAGS, e.g.
$ ./configure CFLAGS="-g -O0" ...
then append -save-temps:
$ ./configure CFLAGS="-g -O0 -save-temps" ...
Then,
$ make main.o
will make main.o, main.i and main.s up-to-date.
To disable -save-temps, of course, rerun ./configure, removing it from
the CFLAGS.
If the project involves C++ compilation, then CXXFLAGS affects the C++
compiler in the same way that CFLAGS affects the C compiler. Note that
the generated preprocessed C++ sources will be called *.ii, not *.i.
With -save-temps enabled, make clean will not delete the *.i and *.s
files. You may not care, since compilation will always clobber them. If you
do care, you may take advantage of automake's standard phony target clean-local,
which is supported to let an autotooling maintainer extend the behaviour of
clean. Add the following recipe to the Makefile.am of each source directory
in the project:
clean-local:
$(RM) *.i *.ii *.s
Then update the autotooling and regenerate Makefiles:
$ autoreconf
$ ./configure ...
While the COMPILE variable in the generated Makefile.in is technically an internal detail, and this solution relies on the compiler to understand -c -S, adding:
.c.s:
$(COMPILE) -c -S $<
to the Makefile.am has worked for as long as I've been using the autotools. It might also be convenient to add:
clean-local:
rm -f *.s
I find this useful in development to have a look at the assembly output for specific configure and CC, CFLAGS options.
The COMPILE variable will be defined as something like:
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
Similarly, for C++ source we have:
.cc.s:
$(CXXCOMPILE) -c -S $<

What is wrong with this Makefile? (header files not found)

I am modifying an old makefile in order to build a C extension for postgreSQL. The Makefile currently looks like this:
PGLIB = /usr/lib/postgresql/8.4/lib
PQINC = /usr/include/postgresql/8.4/server
CC=gcc
override CFLAGS+= $(CFLAGS_SL) -DPG_AGGREGATE
SHLIB = pg_myextlib
SRC = foo.c \
foobar.c
OBJS = foo.o \
foobar.o
all: $(OBJS)
$(CC) -shared -o $(SHLIB)$(DLSUFFIX) $(OBJS) -I$(PQINC)
cp *.so $(PGLIB)
clean:
rm -f $(SHLIB) $(OBJS)
The error I get when I run make is:
common.h:58:22: error: postgres.h: No such file or directory
Which suggests that the include path is not being added (the file exists in $PQINC).
Its a long time since I wrote the Makefile - and I haven't written many since. As an aside, I am pretty sure that 'shared' is not the gcc flag to build shared libs on Ubuntu (my current dev box) - I think the flag should be 'fPIC' - can someone confirm this?
I am runing gcc v4.4.3 on Ubuntu 10.0.4 and compiling for use with PG 8.4
Try moving the -I$(PQINC) from target all to the end of line that starts with override CFLAGS.
Placing -Isomething on the compiler line which turns object files, like those in $(OBJS), into executable will have no effect whatsoever.
You need to do it when you compile the source files.
Since your makefile doesn't explicitly show the rule for processing source files, it may well be using a default one, which is incredibly unlikely to know about PQINC.
You seem to be using the default rules to build foo.o from foo.c, which doesn't have your -I. Try adding the following rule to your Makefile:
.c.o:
$(CC) $(CFLAGS) -c $< -o $# -I$(PQINC)

Resources