Why qemu execute the bin of mipsel failed? - gcc

1.This is my mips assembly code
.data
out_string: .ascii "hello \n"
.text
.global main
main:
li $v0, 4
la $a0, out_string
syscall
li $v0, 10
syscall
2.Then I as the code
mipsel-linux-gun-as --march=mips2 word.S -o word.o
3.I use the gcc link the code
mipsel-linux-gun-gcc -L /usr/mipsel-linux-gun word.o -o word
4.I use the qemu simulation the mips enviroment to execute the bin . The I get some error !!!
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault (core dumped)
Can you help me to compiler the mips code!
Thanks!

Related

Debugging Issue on Assemble Code by using GDB

I tried to use gdb to debug the Assemble code but got error message,it said:
(gdb) run Starting program: /root/assembler_program/bsawp.o
/bin/bash: /root/assembler_program/bsawp.o: cannot execute binary file
The code:
.section .text
.globl _start
_start:
nop
movl 0x12345678 , %ebx
bswap %ebx
movl $1 , %eax
int $0x80
Then I use gdb :
(gdb) break *_start+1
Breakpoint 1 at 0x400079
(gdb) run
Starting program: /root/assembler_program/bsawp
Breakpoint 1, 0x0000000000400079 in _start ()
(gdb) step
Single stepping until exit from function _start,
which has no line number information.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400079 in _start ()
Could you please provide any hint and suggestion?
Thanks!
Best regards
Here:
Starting program: /root/assembler_program/bsawp.o
you are trying to run a relocatable object file. Don't do that.
You must link your object into an executable first. Something like this:
gcc -nostdlib -nostartfile test.s
Here:
Starting program: /root/assembler_program/bsawp
you apparently did link the bsap.o into an executable. The crash is happening here:
(gdb) x/i $pc
=> 0x400079 <_start+1>: mov 0x12345678,%ebx
This instruction is trying to load value from address 0x12345678, into register. But that address does not point to a valid memory location.
You most likely meant for it to load a constant 0x12345678, in which case the instruction you want is:
movl $0x12345678, %ebx
With that fix, I get expected:
(gdb) run
Starting program: /tmp/a.out
[Inferior 1 (process 238270) exited with code 022]
(gdb) p/x 022
$1 = 0x12

yasm writing to PAGEZERO in x86_64 mach-o format

I'm following a assembly book which uses the yasm assembler and ld linker. I'm on OSX 10.12 and I'm trying to assembly to Mach-O format. Unfortunately, I'm receiving a segmentation fault. This is the original .asm file:
BITS 64
segment .data
a dd 4
segment .bss
g resd 1
segment .text
global start
start:
push rbp
mov rbp, rsp
sub rsp, 16
xor eax, eax
leave
ret
I compile it:
yasm -f macho64 -m amd64 -l memory.lst -o memory.o memory.asm
link it:
ld memory.o -o memory
and run it in lldb, I receive this error:
thread #1: tid = 0xb3b4b, 0x0000000000000001, stop reason = EXC_BAD_ACCESS (code=1, address=0x1)
frame #0: 0x0000000000000001
error: error reading data from section __PAGEZERO
In lldb, I ran 'target modules dump sections', and I see that it's __PAGEZERO segment is defined as so:
[0x0000000000000000-0x0000000000001000) --- memory.__PAGEZERO
I looked at a normal Mach-O binary built with clang, and the __PAGEZERO segment looks like this:
[0x0000000000000000-0x0000000100000000) --- test.__PAGEZERO
I then noticed that it's actually the linker that creates the PAGEZERO segment. I believe clang uses a special linker called 'lld'. My question is:
Is my error actually caused by reading from PAGEZERO.
If so, can I tell my linker (ld) to define PAGEZERO in the correct size?
SOLVED: I changed the link command to:
ld memory.o -macosx_version_min 10.12 -lSystem -o memory
This doesn't change the PAGEZERO size, so I'm not sure how it fixed it, but it works now.

Cannot execute binary file (GCC for windows)

I'm trying to compile the piece of assembly code below using gcc. I have finally got it to the point that it compiles an object file, but when I try and run it it get an error back saying 'cannot execute binary file'. I am on windows 10 version 1511.
I am using the msys terminal and compiling by entering
gcc -c main.s -o main.o
I try and execute the file by entering
./main.o
And I get back the error
./main.o: ./main.o: cannot execute binary file
The assembly code is:
.section .text
.global main
main:
mov $4,%eax
mov $1,%ebx
mov $message,%ecx
mov msglength,%edx
int $0x80
mov $1, %eax
mov $0, %ebx
int $0x80
.section .data
message: .ascii "Hello world!"
msglength: .word 12
Any help would be much appreciated.
That is a Linux program and will not work on Windows.
As described in the comments, you need to link the program, remove -c from the gcc command line.

x86_64-pc-cygwin-gcc compile assembly error

I run a simple piece x86-64 assembly code of hello world.
.global main
.text
main:
mov $message, %rdi
sub $8, %rsp
call puts
add $8, %rsp
ret
message:
.asciz "Hello, World"
I use gcc_4.8.2 under cygwin to compile this program under my 64-bit windows os.
gcc -o helloworld helloworld.s
but the compiler always give me the error:
/tmp/ccylxw5q.o:fake:(.text+0x3): relocation truncated to fit: R_X86_64_32S against `.text'
how to solve this problem?
Under gas (which is invoked by gcc) you need to use the movabsq mnemonic if you want to load a 64 bit immediate. Otherwise the assembler will use the 32 bit sign-extending mov, which is indicated by the relocation type of 32S as well. The final address of the message might not be represented as a 32 bit sign-extended value under certain memory layouts which is probably causing the truncation warning.

How can I run this assembly code on OS X?

Starting to learn assembly, I was given some Hello World assembly code created during the class on Linux. I would like to get it to work for 64-bit Mac OS X.
code.asm:
SECTION .data
hola: db "Hola!",10
tam: equ $-hola
SECTION .text
global main
main:
mov edx,tam
mov ecx,hola
mov ebx,1
mov eax,4
int 0x80
mov ebx,0
mov eax,1
int 0x80
This is what I do:
nasm -f macho32 -o object.o code.asm
gcc -m32 -o program object.o
Which tells me:
Undefined symbols for architecture i386: "_main", referenced from:
start in crt1.10.6.o ld: symbol(s) not found for architecture i386
Searching for this error, I found this question: nasm and gcc: 32 bit linking failed (64 bit Mac OS X)
One answer says
The problem you're having is that you're creating a 32-bit Linux(ELF)
object file which isn't compatible with the Mac OS X object format.
Try switching '-f elf' to '-f macho32'.
But I'm definitely using -f macho32. So what would the problem be then?
I've been trying to teach myself some entry-level Assembly programming too, and I ran into similar issues. I had originally compiled using nasm with elf, but that didn't work when I tried to use ld to link the object file and create the executable.
I think the answer you main question "what would the problem be then?" [to get this to run on 64bit MacOSX] is: You are using -f macho32 but expecting it to run on a 64bit machine, you need to change the command option to be -f macho64. Of course, this will not resolve the fact that your assembly code is written for a different architecture (more on that in a bit).
I found this handy answer on the right command to use in this instance to compile and link your code (after you refactor your assembly code to use the proper syntax instead of *nix as duskwuff stated): nasm -f macho64 main.asm -o main.o && ld -e _main -macosx_version_min 10.8 -arch x86_64 main.o -lSystem
After some searching, here's what I learned...
On Mac 64bit, it might be better to use the as assembler instead of nasm (if you want something more native), but if you want more portable code (learn the differences).
nasm doesn't come with the macho64 output type installed by default
Assembly is a pain in the keister (this aside)
Now that my learning rant is out of the way...
Here is the code which should operate on MacOSX 64 using nasm (if you have updated nasm with macho64, credit to Dustin Schultz):
section .data
hello_world db "Hello World!", 0x0a
section .text
global start
start:
mov rax, 0x2000004 ; System call write = 4
mov rdi, 1 ; Write to standard out = 1
mov rsi, hello_world ; The address of hello_world string
mov rdx, 14 ; The size to write
syscall ; Invoke the kernel
mov rax, 0x2000001 ; System call number for exit = 1
mov rdi, 0 ; Exit success = 0
syscall ; Invoke the kernel
Working code I used with the as assembler native to MacOSX64:
.section __TEXT,__text
.global start
start:
movl $0x2000004, %eax # Preparing syscall 4
movl $1, %edi # stdout file descriptor = 1
movq str#GOTPCREL(%rip), %rsi # The string to print
movq $100, %rdx # The size of the value to print
syscall
movl $0, %ebx
movl $0x2000001, %eax # exit 0
syscall
.section __DATA,__data
str:
.asciz "Hello World!\n"
Compile command: as -arch x86_64 -o hello_as_64.o hello_as_64.asm
Link Command: ld -o hello_as_64 hello_as_64.o
Execute Command: ./hello_as_64
Some helpful resources I found along my journey:
AS OSX Assembler Reference: https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/Assembler/Assembler.pdf
Writing 64 Bit Assembly on Mac OSX: http://www.idryman.org/blog/2014/12/02/writing-64-bit-assembly-on-mac-os-x/
Couldn't link object file using ld:
Can't link object file using ld - Mac OS X
OSX i386 SysCalls: http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/mach/i386/syscall_sw.h
OSX Master System Call Definitions: http://www.opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master
OSX Syscall: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/syscall.2.html
You would need to:
Change the label name from main to _main (in both places). Symbol naming works a little bit differently under Mac OS X.
Change the way you pass arguments to the system call. Mac OS X uses a different calling convention for the kernel from Linux; this code is not portable! I don't know as there's any official documentation for how it does work, but looking at the disassembly in GDB for a standard library function like _exit() may be instructive.
Here's _exit on my system, for instance:
<_exit+0>: mov $0x40001,%eax
<_exit+5>: call 0x96f124c2 <_sysenter_trap>
<_exit+10>: jae 0x96f10086 <_exit+26>
<_exit+12>: call 0x96f1007d <_exit+17>
<_exit+17>: pop %edx
<_exit+18>: mov 0x15a3bf9f(%edx),%edx
<_exit+24>: jmp *%edx
<_exit+26>: ret
<_exit+27>: nop
The extra bit set in 0x40001 is... weird, but can be safely ignored here.
The stuff following the call to _sysenter_trap is for error handling.
_sysenter_trap is:
<_sysenter_trap+0>: pop %edx
<_sysenter_trap+1>: mov %esp,%ecx
<_sysenter_trap+3>: sysenter
<_sysenter_trap+5>: nop
All things considered, you're probably better off linking to libSystem (the OS X equivalent of libc) instead of trying to call the kernel directly.
I've wrote a blog post on this topic: https://cs-flex.hashnode.dev/linux-assembly-on-macos
You have 3 main options:
VM -- i don't recommend
Renting a Linux server, not a bad option if you don't mind paying ~20-30$ a month
(My personal best option) using Docker to create a Linux container, that shares a folder (volume) and run assembler there. If you didn't use Docker before -- i still think this option is the best one.
You can read details in my blog post (especially if you didn't use Docker before). But in short, all you will need is this two files:
# Dockerfile
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y gcc
RUN apt-get install -y make
# docker-compose.yml
version: "3"
services:
linux:
image: linux-image
container_name: linux-container
build:
context: .
command: sleep 1000
volumes:
- .:/code
You will be able to run container and connect to it via
docker-compose up # build and run docker container
docker exec -it linux-container bash # "ssh" into container
after this you all your code in the folder with docker files will be "linked" to the folder /code/ inside `Docker. Therefore you can execute it inside docker container as if you were running Linux.

Resources