0

If I write to terminal executing write syscall myself on Mac, it succeeds:

int main() {
    long SYS_WRITE = 0x2000004;
    long STDOUT = 1;

    long result;
    char* str = "Hello world";

    __asm__ __volatile__ (
        "syscall;\n"
        : "=a" (result)
        : "a" (SYS_WRITE), "D" (STDOUT), "S" (str), "d" (10)
        :
    );

    std::cout << result << endl;

    return 0;
}

It prints to console "Hello world" and returns 10 as expected.

However if I try to get on purpose an error, for example, by setting 9999 as file descriptor (which does not exist):

int main() {
    long SYS_WRITE = 0x2000004;
    long STDOUT = 1;

    long result;
    char* str = "Hello world";

    __asm__ __volatile__ (
        "syscall;\n"
        : "=a" (result)
        : "a" (SYS_WRITE), "D" (9999), "S" (str), "d" (10)
        :
    );

    std::cout << result << endl;

    return 0;
}

It returns 9, which corresponds to EBADFD error, which is OK, but the result is not negative. I would expect the error result to be negative, on Linux it is negative.

On Mac, how do I know that syscall returned an error?

Lucas Holt
  • 3,826
  • 1
  • 32
  • 41
Vad
  • 4,052
  • 3
  • 29
  • 34
  • 1
    According to [this post](https://stackoverflow.com/questions/47834513/64-bit-syscall-documentation-for-macos-assembly): "A syscall return `errno` an sets the carry flag on error, instead of returning `-errno` in `rax`" – Galen Dec 25 '17 at 02:25
  • 1
    Almost impresively this question is about two languages and neither of them are C – jess Dec 25 '17 at 02:31
  • 2
    Not related to your question but something you should consider. The `syscall` instruction clobbers RCX and R11 which should be added to your clobber list. – Michael Petch Dec 25 '17 at 04:32
  • @MichaelPetch Thank you very much! – Vad Dec 25 '17 at 10:28
  • @Galen Thanks, it looks like you are right, if you post that as an answer I will accept that. – Vad Dec 25 '17 at 11:23

0 Answers0