Does GCC generate wrong assembly code for the "jal" instruction of riscv? - gcc

generate jal instruction for riscv gets the unexpected code
I have a riscv assembly code in test_jal.s:
jal a0, 42
And I compile it with
riscv64-linux-gnu-gcc -c -Wl,-Ttext=0x0 -nostdlib -mno-relax -o test_jal test_jal.s
Then I generate the raw riscv binary by
riscv64-linux-gnu-objcopy -O binary test_jal test_jal.bin
I use hexdump -C test_jal.bin to generate its hex code:
6F 05 00 00
Then I use riscv64-linux-gnu-objdump to disasm it. I got
jal a0,0x0
May I do something wrong?
System: WSL ubuntu 22.04 gcc verison: 9.3.0

Related

clang appears to use gcc

When I compile a simple hello world program using clang, in the comments of the elf64 file I still find information related to GCC. Why? I'm using clang not gcc.
I'm using ubuntu 16.04.
username#ubuntu:~$ clang++ -stdlib=libc++ test.cpp
username#ubuntu:~$ objdump --full-contents --section=.comment a.out
a.out: file format elf64-x86-64
Contents of section .comment:
0000 4743433a 20285562 756e7475 20352e34 GCC: (Ubuntu 5.4
0010 2e302d36 7562756e 7475317e 31362e30 .0-6ubuntu1~16.0
0020 342e3429 20352e34 2e302032 30313630 4.4) 5.4.0 20160
0030 36303900 636c616e 67207665 7273696f 609.clang versio
0040 6e20342e 302e3020 28746167 732f5245 n 4.0.0 (tags/RE
0050 4c454153 455f3430 302f6669 6e616c29 LEASE_400/final)
0060 00 .
username#ubuntu:~$
test.cpp is:
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << argc << std::endl;
return 0;
}
I also ran
username#ubuntu:~$ sudo update-alternatives --config c++
[sudo] password for username:
There are 2 choices for the alternative c++ (providing /usr/bin/c++).
Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/g++ 20 auto mode
* 1 /usr/bin/clang++-libc++ 5 manual mode
2 /usr/bin/g++ 20 manual mode
Press <enter> to keep the current choice[*], or type selection number:
username#ubuntu:~$
Is this ok? why?
It's because you're linking with a C runtime (from Glibc) built with GCC, and the linker is merging the two together.
$ clang++ -c --stdlib=libc++ test.cpp
$ objdump --full-contents --section=.comment test.o
test.o: file format elf64-x86-64
Contents of section .comment:
0000 00636c61 6e672076 65727369 6f6e2034 .clang version 4
0010 2e302e30 20287461 67732f52 454c4541 .0.0 (tags/RELEA
0020 53455f34 30302f66 696e616c 2900 SE_400/final).
$ clang++ --verbose test.o
"/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crt1.o /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crti.o /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/crtbegin.o -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1 -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64 -L/usr/bin/../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../.. -L/usr/bin/../lib -L/lib -L/usr/lib test.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/crtend.o /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crtn.o
$ objdump --full-contents --section=.comment /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crt1.o
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crt1.o: file format elf64-x86-64
Contents of section .comment:
0000 00474343 3a202847 4e552920 362e332e .GCC: (GNU) 6.3.
0010 31203230 31373033 303600 1 20170306.
$ objdump --full-contents --section=.comment a.out
a.out: file format elf64-x86-64
Contents of section .comment:
0000 4743433a 2028474e 55292036 2e332e31 GCC: (GNU) 6.3.1
0010 20323031 37303330 3600636c 616e6720 20170306.clang
0020 76657273 696f6e20 342e302e 30202874 version 4.0.0 (t
0030 6167732f 52454c45 4153455f 3430302f ags/RELEASE_400/
0040 66696e61 6c2900 final).
My system has slightly different versions from yours, but you can see that the Clang-compiled object only has the Clang identifier in it, the C runtime object has the GCC identifier in it, and the final binary has both.

How to specify entry address for a macho file

I have an asm file test.S:
.text
.globl start
start:
movw %cs, %ax
movw %ax, %ds
Then I execute
clang -m32 -fno-builtin -Wall -ggdb -nostdinc -fno-stack-protector -O0 -nostdinc -c test.S -o test.o
ld test.o -o test.bin
gobjdump -S test.bin
I get
test.bin: file format mach-o-i386
Disassembly of section .text:
00001ffa <start>:
1ffa: 66 8c c8 mov %cs,%ax
1ffd: 66 8e d8 mov %ax,%ds
Notice that the address of start is 0x00001ffa, my question is how can I specify this address? I tried to use ld -segaddr, but it doesn't work. My OS is OS X 10.11

gcc -fno-stack-protector for linking not work

My gcc version : gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
the following is my makefile
all : main.o utility.o
gcc -fno-stack-protector -Wl,-z,execstack -o binary main.o utility.o -lcrypto
main : main.c
gcc -z execstack -fno-stack-protector main.c -c
utility: utility.c
gcc -z execstack -fno-stack-protector utility.c -c
The file utility.o and main.o does not have stack guard
But after linking there are some stack guard
objdump -D binary | grep chk
080488d0 <__stack_chk_fail#plt>:
8048e30: e8 9b fa ff ff call 80488d0 <__stack_chk_fail#plt>
80494dd: e8 ee f3 ff ff call 80488d0 <__stack_chk_fail#plt>
80498e2: e8 e9 ef ff ff call 80488d0 <__stack_chk_fail#plt>
8049b92: e8 39 ed ff ff call 80488d0 <__stack_chk_fail#plt>
8049c9e: e8 2d ec ff ff call 80488d0 <__stack_chk_fail#plt>
8049da2: e8 29 eb ff ff call 80488d0 <__stack_chk_fail#plt>
804a137: e8 94 e7 ff ff call 80488d0 <__stack_chk_fail#plt>
How to disable it?
the following is my makefile
gcc -z execstack -fno-stack-protector main.c -c
That command is bogus; if anything it should have -Wl,-z,execstack. However, since that's a linker option, and you are not linking here, best to remove -z exestack completely.
But after linking there are some stack guard
The calls to __stack_chk_fail must be coming from some code linked into your binary. Perhaps from libcrypto.a, or from libgcc.a. You can see where they are coming from, in two ways:
gcc -fno-stack-protector -Wl,-z,execstack -o binary main.o utility.o \
-lcrypto -Wl,-y,__stack_chk_fail
will produce messages like this:
/some/libfoo.a(bar.o): reference to __stack_chk_fail # you care about this one!
/usr/lib/libc.so.6: definition of __stack_chk_fail
Or you can use the binary you already built:
objdump -d binary | egrep '>:$|__stack_chk_fail' | grep -B1 __stack_chk_fail
That should tell you which functions inside the binary reference __stack_chk_fail, and from that you should be able to guess where these functions are coming from.
P.S. Unless you are studying buffer overflow exploitation techniques, disabling stack protector and linking with -z,execstack is a really bad idea.

Nasm on Mac OS X - how to compile and read the debug

I'm trying to learn assembly and I'm using Nasm v2.10.07 on Mac OS X (Snow Leopard).
I can compile, but I need to read the Debug file, that is a .o file.
This is what I compile:
global _main
section.data
M db 5,4,3,2,1
dim equ $-M
section.text
_main:
mov edi, M
mov eax, 0
mov ebx, 1
int 80h
This is how I compile:
nasm -f elf -g -F stabs myfile.asm -o myfile.o
And this is the result:
ELF����������������������#�������4�����(�
�������������������������������������������������������������������–������������������������������������?��������������������������������0��M��������������������������������Ä��ê���������������"����������������2������������������*��� �����������P�����������������4��������������`��T����������������:��������������¿��������������������C��� �����������–��0���������������ø����∏����ª���ÕÄ�%define $�The Netwide Assembler 0.98.40 (Apple Computer, Inc. build 11)���.text�.comment�.shstrtab�.symtab�.strtab�.rel.text�.stab�.stabstr�.rel.stab��%d����������������������������Òˇ�������������Òˇ������������������������������������������������������Òˇ�������������,�������������myfile.asm�section.data�M�dim�section.text�_main��%define $_%1 ������%define������������d�����������D����������D���������D��
�������D� ��������D�
�����%define $_%�myfile.asm��%de����� �����,�����8�����D�����P�����
So, what should I do to read in the correct way the debug without those strange symbols?
To show the contents of the .stabs section, use objdump -g myfile.o or objdump -G myfile.o
To get the full source code with line numbers taken from the debug section, use objdump -S -l myfile.o

Compiling ARM .s file on Mac

I am on Mac Os X and I am having trouble compiling a .s ARM assembly file.
my .s file is this:
mov r0, r1
just to see if it works.
but when i do
arm-elf-as my.s
i get an
a.out file.
i do
chmod +x a.out
and
./a.out
but it says
cannot execute binary file
this has me confused, because it should be able to execute if i compiled it with arm-elf-as. How do i go about compiling this .s?
You're assembling it allright, you just can't run it on a Mac since Macs don't have ARM CPUs. If you install Xcode with iOS support, you can compile ARM code:
# the file
$ cat foo.s
mov r0, r1
# compile with llvm-gcc
$ /Developer/Platforms/iPhoneOS.platform/usr/bin/llvm-gcc-4.2 -arch armv6 -c foo.s
# resulting file is ARM object file
$ file foo.o
foo.o: Mach-O object arm
# and you can disassemble it
$ otool -v -t foo.o
foo.o:
(__TEXT,__text) section
00000000 e1a00001 mov r0, r1
You won't be able to run anything, because for that you'll need a runtime system and and ARM CPU. You can use -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk or similar to compile for the iPhoneOS for example.

Resources