I'am reading this Tuto, and I'am trying to link the application using this command: ld test.o –o test.bin, the linker doesn't recognize the -o option :
ld: cannot find –o: No such file or directory
Using ld -help the option -o exist but i don't understand why I'am getting this problem.
This is the linker version.
$ ld -version
GNU ld (GNU Binutils for Ubuntu) 2.24
Copyright 2013 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
My good eyes and my bitter experience tell me that you must have copied/pasted some text coming from MS-Office where the dash (-) has been converted to another dash which is unicode or whatever. Notice the length of the dash character in your text.
Actually, the tuto you were refering to is the one at fault, ex in this line:
ld –Ttext 0x7c00 --oformat=binary test.o –o test.bin
Note the 2 infamous "long-dashes" that cannot work on a command line.
Your command as-is, followed by the retyped command. notice something?
ld test.o –o test.bin # long dash, fails
ld test.o -o test.bin # good one, short dash
Since the dash is not the correct one, ld assumes that this is an object file and tries to open it, hence the error.
Related
I'm trying to learn about assembly with the book "Programming from the ground up". The book covers only 32 bit instructions. Is there a way to run the example codes on 64 bit Ubuntu system? I can't understand the stuff on the man page of the GNU assembler but I heard the -m32 flag should do it. But it's not a recognized option.
How do I get the examples on the book to work with ease?
When your assembler and linker are x86_64 versions, the options to produce i386 (32-bit) output are
as --32
ld -m elf_i386
You don't have to use as and ld just because you're working with assembly code. gcc can be used, and in that case you would use -m32.
gcc -m32 -nostdlib myprog.s -o myprog
From the as man page:
Target i386 options:
[--32|--n32|--64] [-n]
[-march=CPU[+EXTENSION...]] [-mtune=CPU]
I'm not sure if it works, just try --32 or --n32.
(-m32 seems to ge the corresponding gcc flag.)
Creating a 32-bit executable on a 64-bit PC requires that you "warn" the linker that a 32-bit elf file is coming:
$ nasm -f elf -g -F stabs eat.asm
$ ld -o eat eat.o -melf_i386
That's what the melf_i386 directive does: It tells ld that the eat.o file is an elf32 linkable object file. The invocation of NASM is the same as you'd use on a 32-bit PC.
Thanks #Jeff Duntemann
I am new to linux programming and learning it from The Linux Programming Interface by Michael Kerrisk.
I have to compile my first program that has dependencies.
Directory structure:
--linux-programs
|--seek_io.c
|--lib
|--tlpi_hdr.h
|--error_functions.h
|--error_functions.c
|--get_num.h
|--ename.c.inc
I want to compile seek_io.c program with dependencies in the lib directory, so that I can see how the program works.
I tried a few things, absolutely clueless on how they work following this stackoverflow answer. I get all sorts of errors as I am an absolute beginner to Linux programming, not to programming, linux OS and C.
Trials:
gcc -I ./lib/ -c ./lib/error_functions.c and then gcc -o seek_io.c ./error_function.o gives error:
/usr/lib/gcc/x86_64-linux-gnu/crt1.o: In function _start:
(.text+0x20): undefined reference to main
collect2: error: ld returned 1 exit status
After this run, on ls I find that my seek_io.c is not listed.
Basically the author of the book says for tlpi_hdr.h file:
This header file includes various other header files used by many of the example programs, defines a Boolean data type, and defines macros for calculating the minimum and maximum of two numeric values. Using this header file allows us to make the example programs a bit shorter.
Link to codes for files mentioned above:
tlpi_hdr.h
error_functions.h
error_functions.c
get_num.h
get_num.c
seek_io.c
The problem is with your second gcc command, where you're using the -o file to specify the output file where to store the resulting executable file, but passing it the name of the C source file seek_io.c instead...
gcc -o seek_io.c ./error_function.o
This means link file error_function.o and store the executable in seek_io.c. This fails because there is no main function, which is needed for a standalone executable, so your C source file is not overwritten by the failing link command.
You can fix this easily by passing the -o option a proper output file name, which in the case (of this link command) should be the name of the executable that you want to create, such as seek_io:
gcc -o seek_io seek_io.c ./error_function.o
(But this will fail without a -I ./lib/, since seek_io.c includes tlpi_hdr.h which is in that directory. If you add it to that command, it should work.)
You can also decide to split the compile and link steps in two separate steps (the command above will both compile seek_io.c into an object file and then link the two object files into an executable) with:
$ gcc -I ./lib/ -c ./lib/error_functions.c
$ gcc -I ./lib/ -c seek_io.c
$ gcc -o seek_io seek_io.o error_function.o
One final nitpick is that for the -I flag to specify the directories where to search for the include files, the more common usage has no space between the flag itself and the directory name, so you'll most commonly see -I./lib or even -Ilib.
$ gcc -Ilib -c ./lib/error_functions.c
$ gcc -Ilib -c seek_io.c
$ gcc -o seek_io seek_io.o error_function.o
I am trying to follow the exercise in the book PC Assembly by Paul Carter. http://pacman128.github.io/pcasm/
I'm trying to run the program from 1.4 page 23 on Ubuntu 18. The files are all available on the github site above.
Since original code is for 32bit I compile using
nasm -f elf32
for first.asm and asm_io.asm to get the object files. I also compile driver.c
I use the linker from gcc and run
gcc -m32 -o first first.o asm_io.o driver.o
but it keeps giving me a bun of errors like
undefined reference to '_scanf'
undefined reference to '_printf'
(note _printf appears instead of printf because some conversion is done in the file asm_io.asm to maintain compatibility between windows and linux OS's)
I don't know why these errors are appearing. I also try running using linker directly
ld -m elf_i386 -e main -o first -first.o driver.o asm_io.o -I /lib/i386-linux-gnu/ld-linux.so.2
and many variations since it seems that its not linking with the C libraries.
Any help? Stuck on this for a while and couldn't find a solution on similar questions
Linux doesn't prepend _ to names when mapping from C to asm symbol names in ELF object files1.
So call printf, not _printf, because there is no _printf in libc.
Whatever "compatibility" code did that is doing it wrong. Only Windows and OS X use _printf, Linux uses printf.
So either you've misconfigured something or defined the wrong setting, or it requires updating / porting to Linux.
Footnote 1: In ancient history (like over 20 years ago), Linux with the a.out file format did use leading underscores on symbol names.
Update: the library uses the NASM preprocessor to %define _scanf scanf and so on, but it requires you to manually define ELF_TYPE by assembling with nasm -d ELF_TYPE.
They could have detected ELF32 or ELF64 output formats on their own, because NASM pre-defines __OUTPUT_FORMAT__. Someone should submit a pull-request to make this detection automatic with code something like this:
%ifidn __OUTPUT_FORMAT__, elf32
%define ELF_TYPE 32
%elifidn __OUTPUT_FORMAT__, elf64
%define ELF_TYPE 64
%endif
%ifdef ELF_TYPE
...
%endif
I'm trying to learn about assembly with the book "Programming from the ground up". The book covers only 32 bit instructions. Is there a way to run the example codes on 64 bit Ubuntu system? I can't understand the stuff on the man page of the GNU assembler but I heard the -m32 flag should do it. But it's not a recognized option.
How do I get the examples on the book to work with ease?
When your assembler and linker are x86_64 versions, the options to produce i386 (32-bit) output are
as --32
ld -m elf_i386
You don't have to use as and ld just because you're working with assembly code. gcc can be used, and in that case you would use -m32.
gcc -m32 -nostdlib myprog.s -o myprog
From the as man page:
Target i386 options:
[--32|--n32|--64] [-n]
[-march=CPU[+EXTENSION...]] [-mtune=CPU]
I'm not sure if it works, just try --32 or --n32.
(-m32 seems to ge the corresponding gcc flag.)
Creating a 32-bit executable on a 64-bit PC requires that you "warn" the linker that a 32-bit elf file is coming:
$ nasm -f elf -g -F stabs eat.asm
$ ld -o eat eat.o -melf_i386
That's what the melf_i386 directive does: It tells ld that the eat.o file is an elf32 linkable object file. The invocation of NASM is the same as you'd use on a 32-bit PC.
Thanks #Jeff Duntemann
I am now using BACKTRACK 5 which is almost like ubuntu, a debian and its 32 bit, and I have ins talled nasm, I went to dr. paulcarter's assembly language tutorials and downloaded his sample programs (Linux). I went to the directory where the sample programs are and executed the following instruction
~/Desktop/linux-ex# nasm -f coff array1.asm
~/Desktop/linux-ex# gcc -o array1 array1.o array1c.c
array1.o: file not recognized: File format not recognized
collect2: ld returned 1 exit status
The above execution instructions have been provided in the source file comments
How can I make these and later my own programs work?
The Linux kernel supports various binary formats. coff is a particularly old one, and if the kernel still supports it at all, it might not be enabled in modern distributions. Try -f elf instead of -f coff.