ld: file not found: i386 - macos

I'm trying to link a 32Bit simple object file with ld, but I only get this error message
ld: warning: option -m is obsolete and being ignored
ld: file not found: i386
On first sight I thought it was just a simple syntax error, because i386 is not a file, it should be the architecture. My command line looks like this:
ld add64.o -m i386 -static -o JulianTest
According to the man pages this syntax should be correct.
Maybe I should also mention that I used :
nasm -g -f elf32 myfile.asm
to compile and that I'm on a 64Bit-System (OS X), furthermore this is my add64.asm:
section .data
section .bss
section .text
global _start
mov eax, 0x11111111
mov ebx, 0x22222222
mov ecx, 0x33333333
mov edx, 0x44444444
add ebx, edx
adc eax, ecx
int 80h
Any thoughts?

Related

Compile assembly (NASM with int 80h system calls) in windows

I am learning to code assembly (NASM). But i have problem, i am coding online but i want to convert this code below to exe and run it. (By clicking double click on it, not in cmd). And i dont have a clue how to do it. i know i must use a nasm from https:://www.nasm.us and a linker. For the linker i want to use ld from mingw. but i dont know how to do it. i didnt find any thing on the internet
section .data
msg: db "Eneter your name : ", 10
msg_l: equ $-msg
hello: db "Hello, "
hello_l: equ $-hello
section .bss
name: resb 255
section .text
global _start:
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msg_l
int 80h
mov eax, 3
mov ebx, 0
mov ecx, name
mov edx, 255
int 80h
mov eax, 4
mov ebx, 1
mov ecx, hello
mov edx, hello_l
int 80h
mov eax, 4
mov ebx, 1
mov ecx, name
mov edx, 255
int 80h
mov eax, 1
mov ebx, 0
int 80h
The best way to work with linux in windows is to use wsl2. The windows subsystem will allow you to use real linux system calls. There is a learning curve but its worth it.
Follow a guide on how to install ws2.
Go to the windows store and download one of the few linux terminals. I use ubuntu.
Install gcc in the terminal so that you will have a gnu compiler, gnu assembler, and the gnu linker(ld).
Install nasm in the terminal. Not the windows app version.
After everything is set up, you can get a nice workflow going.
you would open the terminal.
change directories which will get you into the c drive: cd /mnt/c
create a folder in the c drive where you want to do your work
change directories to that folder: cd foldername
create a nasm asm file and put some code into it.
then you can use nasm to assemble, ld to link, execute
When you assemble with nasm you can now use elf:
nasm -f elf32 main.asm
ld -m elf_i386 main.o -o main
./main
or:
nasm -f elf64 main.asm
ld main.o -o main
./main

Nasm Dwarf Error Bad Offset

I have a simple Hello World program for Windows in pure x86 assembly code that I have compiled and linked with nasm and ld. The problem I am running into is that I can't get DWARF debugging to work. I am using gdb from Mingw64 (i686-posix-dwarf-rev1). This same problem happens if I use gcc to link instead of ld. But, the program builds fine, and if I use STABS debugging, then everything is fine and dandy.
EDIT: Oops, I completely forgot to give the error that gdb shows.
...Dwarf Error: bad offset (0x407000) in compilation unit header (offset 0x0
+ 6) [in module C:\Projects\AsmProjects\HelloWorldWin32\bin\x86\hello32.exe]
(no debugging symbols found)...done
The versions of each program are:
gdb 7.10.1
nasm 2.12.02
ld 2.25
gcc 6.2.0
These are the flags I'm sending to nasm: -f elf32 -Fdwarf -g
These are the flags for gcc link: -o $(BDIR)/x86/$#.exe $^ -L$(Mingw64-x86libs) -lkernel32 -luser32
And these are from ld link:
-mi386pe -o $(BDIR)/x86/$#.exe $^ -L$(Mingw64-x86libs) -lkernel32 -luser32
I have a pretty big makefile, so I'm trying to give the least information that is absolutely neccessary.
Here is the source code for the program:
global _main
extern _GetStdHandle#4
extern _WriteFile#20
extern _ExitProcess#4
section .text
_main:
push ebp
mov ebp,esp
; GetstdHandle( STD_OUTPUT_HANDLE)
push -11
call _GetStdHandle#4
mov ebx, eax
; WriteFile( hstdOut, message, length(message), &bytes, 0);
push 0
push esp
push message_end
push message
push ebx
call _WriteFile#20
; ExitProcess(0)
push 0
call _ExitProcess#4
section .data
message db 'Hello, World',10
message_end equ $ - message
This is not a proper answer but was too long for the comment section.
I compiled on Ubuntu and then ran dwarfdump
It gave an error that may be related to the offset error.
dwarfdump ERROR: dwarf_get_globals: DW_DLE_PUBNAMES_VERSION_ERROR (123)
From a similar error on LLVM, I conclude that the dwarf version information is possibly corrupt or unsupported.
This post indicates that the dwarf information is sensitive to the proper section names. The example appears to have the section names right however.
Have you tried a 64-bit version? Perhaps a clue will appear.
This program appears to work fine Ubuntu. Can you try it on Mingw64?
section .text
global _start ;must be declared for linker (ld)
_start: ;tell linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string

How to get this simple assembly to run?

This is my first ever attempt at programming with assembly. I'm using a 64 bit Mac OS. I'm also using NASM. I've done a lot of looking around for a solution, but I can't find anything that works for my machine.
Can anyone help me solve this problem? Here is the code and error, thanks!
hello.asm
global start
section .text
start:
mov rax, 1
mov rdi, 1
mov rsi, message
mov rdx, 13
syscall
mov eax, 60
xor rdi, rdi
syscall
message:
db "Hello, World", 10
my attempt at executing:
nasm -f macho64 hello.asm -o hello.o
ld -arch i386 -o hello hello.o
./hello
the error
ld: warning: -macosx_version_min not specified, assuming 10.10
ld: warning: ignoring file hello.o, file was built for unsupported file format ( 0xCF 0xFA 0xED 0xFE 0x07 0x00 0x00 0x01 0x03 0x00 0x00 0x00 0x01 0x00 0x00 0x00 ) which is not the architecture being linked (i386): hello.o
Undefined symbols for architecture i386:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture i386
The reason for your linker error is that you created a 64-bit macho object using NASM, but then targeted i386 for the executable. What you likely were after was a 64-bit executable, which could be done by removing -arch like this:
ld -o hello hello.o
As for your segfault when running your program, it seems that you likely followed a tutorial that may have been designed for Linux. OS/X isn't base upon Linux, it derived from BSD so the Syscalls are different. We could tell you were using Linux Syscalls because syscall 1 is sys_write and sys_exit is rax = 60. This unfortunately isn't the same for OS/X. In 64-bit OS/X code sys_exit is rax=0x20000001 and sys_write is rax=0x20000004 .
Your code would have to be changed to:
global start
section .data
message: db "Hello, World", 10
section .text
start:
mov rax, 0x20000004
mov rdi, 1
mov rsi, message
mov rdx, 13
syscall
mov rax, 0x20000001
xor rdi, rdi
syscall
You'll also observe I explicitly declared a .data section and placed your variable in it. In some environments it may cause problems if data variables are placed in the code.
If creating 32-bit code on OS/X (you aren't in this case) the Syscalls have 0x20000000 subtracted from each. So in 32-bit OS/X code sys_exit is eax=0x1 and sys_write is eax=0x4 .
A reference for all the Syscalls (and their parameters) on OS/X can be found in this Apple information. Just add 0x20000000 to each number in the first column of the chart for 64-bit assembler code.
You probably want to find a 64-bit OS/X tutorial about Syscalls. This is a simple one

Why am I getting a warning about absolute addressing with immediate operands?

This little program works fine on OS X, using nasm:
global _main
extern _puts
section .text
default rel
_main:
push rbp
lea rdi, [message]
call _puts
pop rbp
ret
message:
db 'Hello, world', 0
Here's how it runs:
$ nasm -fmacho64 hello.asm && gcc hello.o && ./a.out
Hello, world
But if I replace the LEA instruction (with a memory operand) with an equivalent MOV immediate:
global _main
extern _puts
section .text
default rel
_main:
push rbp
mov rdi, message ; <---- Should have same effect as lea rdi, [message]
call _puts
pop rbp
ret
message:
db 'Hello, world', 0
The program will run but with a warning message, that I know has been asked about before on Stack Overflow:
$ nasm -fmacho64 hello.asm && gcc hello.o && ./a.out
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from hello.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
Hello, world
My question is why does this warning occur? I see the error is complaining about the linker not liking absolute addressing; however the MOV command is clearly using an immediate operand, not an absolute address! Is the warning mislabeled? I'm puzzled that
As an aside, this distinction does not happen under Linux. Removing default rel and the underscores on main and puts gives me a warning-free run on Ubuntu. What is OS X doing differently here? Is it a case of the assembler default configurations being set differently? Or is it something weird like OS X following AMD's ABI more closely than Ubuntu?

Compile intel assembly with gcc/mingw

I want to compile intel syntax assembly using gcc. Is it possible? because I cant find something similar. I've only found this post.
Here is the code I am trying to compile.
global _main
section .text
_main:
mov eax, -1
ret
If this is not possible please provide alternative options in your answer.
Adding a .intel_syntax directive works for me:
.globl _main
.intel_syntax
_main:
mov eax, -1
ret
Assembling and running:
$ gcc -o example example.s; ./example; echo $?
255

Resources