Reputation: 33
This is my code.
long doSystemCall(const char *path) {
register long x0 asm("x0") = 0;
register long x1 asm("x1") = (long) path;
register long x2 asm("x2") = 0;
register long x3 asm("x3") = 0;
register long x8 asm("x8") = __NR_faccessat;
__asm__ volatile("svc #0"
:"=r"(x0)
:"0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8)
:"memory"
);
__android_log_print(ANDROID_LOG_INFO, "SYSCALL", "Result: %li", x0);
return x0;
}
The return values it gives are 0
, -2
or -13
, however faccessat
should only return 0
or -1
. How can I fix this?
The decompiled pseudocode of my code looks like this.
signed __int64 __fastcall sub_E558(const char *a1)
{
signed __int64 v1; // ST30_8
v1 = linux_eabi_syscall(__NR_faccessat, 0, a1, 0, 0);
__android_log_print(4LL, "SYSCALL", "Result: %li", v1);
return v1;
}
And these are the instructions of the function.
SUB SP, SP, #0x50
STP X29, X30, [SP,#0x40+var_s0]
ADD X29, SP, #0x40
STUR X0, [X29,#var_8]
MOV X0, XZR
STUR X0, [X29,#var_10]
LDUR X8, [X29,#var_8]
STUR X8, [X29,#var_18]
STR X0, [SP,#0x40+var_20]
STR X0, [SP,#0x40+var_28]
MOV W9, #0x30
MOV W8, W9
STR X8, [SP,#0x40+var_30]
LDUR X0, [X29,#var_10]
LDUR X1, [X29,#var_18]
LDR X2, [SP,#0x40+var_20]
LDR X3, [SP,#0x40+var_28]
LDR X8, [SP,#0x40+var_30]
SVC 0
STUR X0, [X29,#var_10]
LDUR X3, [X29,#var_10]
ADRP X1, #aSyscall@PAGE ; "SYSCALL"
ADD X1, X1, #aSyscall@PAGEOFF ; "SYSCALL"
ADRP X2, #aResultLi@PAGE ; "Result: %li"
ADD X2, X2, #aResultLi@PAGEOFF ; "Result: %li"
MOV W0, #4
BL .__android_log_print
LDUR X8, [X29,#var_10]
STR W0, [SP,#0x40+var_34]
MOV X0, X8
LDP X29, X30, [SP,#0x40+var_s0]
ADD SP, SP, #0x50
RET
Upvotes: 0
Views: 548
Reputation: 126110
You're confusing the libc wrapper API with the direct syscall ABI -- only the libc wrapper returns errors in errno. The direct system call will return a small neagtive value (with the error code), at least on Linux. The libc wrapper will test the return value, and if it is the range -4096..-1, will negate it and store it in errno (and then return -1). Other UNIX variants (BSD) return the error indication in a flag (usually carry flag) with the error value in the return register.
Upvotes: 7