Hi folks,

I've been playing with shared-libraries and x86_64 assembler and ran clean off the edge of the world as described in the begginers books I've bought about learning assembly language. I've done my best to get it working and appear to have reached what looks to me like a working set-up, but debugging through it shows that I'm getting an error code from sys_write of -14, EFAULT (I think). I've added some code below and some gdb pastes. I'd appreciate any help anyone can give to get this working!

At present, the code runs but doesn't print anything out, nor does it emit an error. As you can probably tell from the function name, I'm trying to get JNI->Assembly working for a 64-bit shared library. The Java code (not included here) runs without exception, and similarly doesn't print the expected message to stdout.

Regards

Michael

Test.c

extern void Java_HelloWorld_sayHello();

int main() {
       Java_HelloWorld_sayHello();
       exit(0);
}


HelloWorld.s


.section .data
       hellomsg:       .asciz  "Hello, World!!\n"

.section .text
       .type   Java_HelloWorld_sayHello, @function
       .globl  Java_HelloWorld_sayHello

Java_HelloWorld_sayHello:
       pushq   %rbp
       movq    %rsp, %rbp

       movq    $4, %rax
       movq    $1, %rbx
       leaq    hellomsg(%rip), %rcx
       movq    $15, %rdx

       int     $0x80

       movq    %rbp, %rsp
       popq    %rbp
       ret


Makefile

all: libhello.so Test

Test: libhello.so
       gcc -g -o Test -L. -lhello Test.c

libhello.so: HelloWorld.o
       ld -fPIC -shared -o libhello.so HelloWorld.o -lc

HelloWorld.o:
       as --64 -g -o HelloWorld.o HelloWorld.s

clean:
       rm *.o *.so Test



Various excerpts from my journey through gdb...


(gdb) disassemble
Dump of assembler code for function main:
0x0000000000400558 <main+0>:    push   %rbp
0x0000000000400559 <main+1>:    mov    %rsp,%rbp
0x000000000040055c <main+4>:    mov    $0x0,%eax
0x0000000000400561 <main+9>:    callq  0x400490 <Java_HelloWorld_sayHello@plt>
0x0000000000400566 <main+14>:   mov    $0x0,%edi
0x000000000040056b <main+19>:   callq  0x400470 <exit@plt>
End of assembler dump.

(gdb) break *0x400490
Breakpoint 3 at 0x400490
(gdb) nexti

Breakpoint 3, 0x0000000000400490 in Java_HelloWorld_sayHello@plt ()
(gdb) disassemble
Dump of assembler code for function Java_HelloWorld_sayHello@plt:
0x0000000000400490 <Java_HelloWorld_sayHello@plt+0>:    jmpq   *2098298(%rip)        # 0x600910 <_GLOBAL_OFFSET_TABLE_+40>
0x0000000000400496 <Java_HelloWorld_sayHello@plt+6>:    pushq  $0x2
0x000000000040049b <Java_HelloWorld_sayHello@plt+11>:   jmpq   0x400460
End of assembler dump.

# ...

(gdb) nexti
0x00000030f78128fb in _dl_runtime_resolve () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
Java_HelloWorld_sayHello () at HelloWorld.s:11
11              pushq   %rbp
Current language:  auto; currently asm
(gdb) disassemble
Dump of assembler code for function Java_HelloWorld_sayHello:
0x00002b8afa0b01e8 <Java_HelloWorld_sayHello+0>:        push   %rbp
0x00002b8afa0b01e9 <Java_HelloWorld_sayHello+1>:        mov    %rsp,%rbp
0x00002b8afa0b01ec <Java_HelloWorld_sayHello+4>:        mov    $0x4,%rax
0x00002b8afa0b01f3 <Java_HelloWorld_sayHello+11>:       mov    $0x1,%rbx
0x00002b8afa0b01fa <Java_HelloWorld_sayHello+18>:       lea    2097399(%rip),%rcx        # 0x2b8afa2b02f8 <hellomsg>
0x00002b8afa0b0201 <Java_HelloWorld_sayHello+25>:       mov    $0xf,%rdx
0x00002b8afa0b0208 <Java_HelloWorld_sayHello+32>:       int    $0x80
0x00002b8afa0b020a <Java_HelloWorld_sayHello+34>:       mov    %rbp,%rsp
0x00002b8afa0b020d <Java_HelloWorld_sayHello+37>:       pop    %rbp
0x00002b8afa0b020e <Java_HelloWorld_sayHello+38>:       retq
End of assembler dump.

# ...

(gdb) nexti
(gdb) nexti
(gdb) nexti
23              movq    $1, %rbx
(gdb) info reg
rax            0x4      4
rbx            0x30f7a1bbc0     210313001920
rcx            0x400580 4195712
rdx            0x7fff7cc166a8   140735286437544
rsi            0x7fff7cc16698   140735286437528
rdi            0x1      1
rbp            0x7fff7cc165a0   0x7fff7cc165a0
rsp            0x7fff7cc165a0   0x7fff7cc165a0
r8             0x30f7f522d0     210318467792
r9             0x30f780d660     210310846048
r10            0x0      0
r11            0x2b8afa0b01e8   47875900506600
r12            0x0      0
r13            0x7fff7cc16690   140735286437520
r14            0x0      0
r15            0x0      0
rip            0x2b8afa0b01f3   0x2b8afa0b01f3 <Java_HelloWorld_sayHello+11>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0

(gdb) nexti
(gdb) nexti
(gdb) nexti
27              int     $0x80
(gdb) info reg
rax            0x4      4
rbx            0x1      1
rcx            0x2b8afa2b02f8   47875902604024
rdx            0xf      15
rsi            0x7fff7cc16698   140735286437528
rdi            0x1      1
rbp            0x7fff7cc165a0   0x7fff7cc165a0
rsp            0x7fff7cc165a0   0x7fff7cc165a0
r8             0x30f7f522d0     210318467792
r9             0x30f780d660     210310846048
r10            0x0      0
r11            0x2b8afa0b01e8   47875900506600
r12            0x0      0
r13            0x7fff7cc16690   140735286437520
r14            0x0      0
r15            0x0      0
rip            0x2b8afa0b0208   0x2b8afa0b0208 <Java_HelloWorld_sayHello+32>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0

(gdb) x/c 0x2b8afa2b02f8
0x2b8afa2b02f8 <hellomsg>:      72 'H'
(gdb) x/c 0x2b8afa2b02f9
0x2b8afa2b02f9 <hellomsg+1>:    101 'e'
(gdb) x/c 0x2b8afa2b02fa
0x2b8afa2b02fa <hellomsg+2>:    108 'l'

# ...

0x2b8afa2b0305 <hellomsg+13>:   33 '!'
(gdb) x/c 0x2b8afa2b0306
0x2b8afa2b0306 <hellomsg+14>:   10 '\n'
(gdb) x/c 0x2b8afa2b0307
0x2b8afa2b0307 <hellomsg+15>:   0 '\0'

(gdb) nexti
29              movq    %rbp, %rsp
(gdb) info reg
rax            0xfffffffffffffff2       -14
rbx            0x1      1
rcx            0x2b8afa2b02f8   47875902604024
rdx            0xf      15
rsi            0x7fff7cc16698   140735286437528
rdi            0x1      1
rbp            0x7fff7cc165a0   0x7fff7cc165a0
rsp            0x7fff7cc165a0   0x7fff7cc165a0
r8             0x0      0
r9             0x0      0
r10            0x0      0
r11            0x0      0
r12            0x0      0
r13            0x7fff7cc16690   140735286437520
r14            0x0      0
r15            0x0      0
rip            0x2b8afa0b020a   0x2b8afa0b020a <Java_HelloWorld_sayHello+34>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0

(gdb) nexti
(gdb) nexti
31              ret
(gdb) info reg
rax            0xfffffffffffffff2       -14
rbx            0x1      1
rcx            0x2b8afa2b02f8   47875902604024
rdx            0xf      15
rsi            0x7fff7cc16698   140735286437528
rdi            0x1      1
rbp            0x7fff7cc165b0   0x7fff7cc165b0
rsp            0x7fff7cc165a8   0x7fff7cc165a8
r8             0x0      0
r9             0x0      0
r10            0x0      0
r11            0x0      0
r12            0x0      0
r13            0x7fff7cc16690   140735286437520
r14            0x0      0
r15            0x0      0
rip            0x2b8afa0b020e   0x2b8afa0b020e <Java_HelloWorld_sayHello+38>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0




I've understood the RAX line

rax            0xfffffffffffffff2       -14
rbx            0x1      1
rcx            0x2b8afa2b02f8   47875902604024
rdx            0xf      15

as showing an errno of -14, EFAULT. Is that correct? And if it is an EFAULT, why is it a bad address? Looks fine to me...
Posted on 2011-04-12 08:34:42 by michaelg
Wild, wild guess! Apparently, if you use int 0x80 in 64-bit code, you get the old 32-bit interface. Perhaps it isn't comfortable with rip-relative addressing?

Even wilder guess! Attempting to adapt from an example the late Chuck Crayne left for us to study, maybe something like this?


...
    movq $1, %rax  # 64-bit sys_write
    movq $1, %rdi  # STDOUT
    leaq hellomsg(%rip), %rsi
    movq $15, %rdx  # length
    syscall
...


I have no idea if that's even close...

Best,
Frank

Posted on 2011-04-12 13:14:46 by fbkotler
Frank is correct. Read THIS for further details.
Posted on 2011-04-12 14:20:46 by SpooK
Gents,

You're amazing, thanks very much.

One thing I find incredible is the absolute lack of resources online about this sort of thing. Oh well...

Best wishes,

Michael
Posted on 2011-04-12 15:21:52 by michaelg

One thing I find incredible is the absolute lack of resources online about this sort of thing. Oh well...


Not surprising for me... unix jockeys tend to be C zealots as well :lol:
Posted on 2011-04-12 15:36:14 by SpooK


One thing I find incredible is the absolute lack of resources online about this sort of thing. Oh well...


Not surprising for me... unix jockeys tend to be C zealots as well :lol:
More like, why waste time writing documentation for assembly programmers, when that's going to be a very small part of your target audience? Especially when "somebody who wants to do that really should know how to gdb the info himself?" :-)
Posted on 2011-05-18 18:05:58 by f0dder

More like, why waste time writing documentation for assembly programmers, when that's going to be a very small part of your target audience? Especially when "somebody who wants to do that really should know how to gdb the info himself?" :-)


I agree.
Posted on 2011-05-18 20:04:58 by SpooK