Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print error message using errno in assembly language

I am writing to a stdout in assembly language using sys_write system call and I want to print an error message if an error happens during write and then exit gracefully.

I am only able to exit but cant print error message using errno and perror. Any suggestions how to do handle the error if syscall fails. I want to print error message depending on the type of error that happened. I am on Ubuntu 14.04 and I am using nasm to compile my assembly code. Currently I am doing only this:

test rax,rax    ; Lets make sure the file descriptor is valid
js  skipWrite   ;
like image 872
user2281107 Avatar asked Mar 08 '15 02:03

user2281107


People also ask

How do I print errno?

Your program can use the strerror() and perror() functions to print the value of errno. The strerror() function returns a pointer to an error message string that is associated with errno. The perror() function prints a message to stderr.

What is the type of errno?

errno is a preprocessor macro used for error indication. It expands to a static (until C++11) thread-local (since C++11) modifiable lvalue of type int. Several standard library functions indicate errors by writing positive integers to errno .

What does errno 0 mean?

" A value of 0 indicates that there is no error in the program." and "As a good practice, developer should set errno to 0 at the time of initialization of the program" By convention we check the errno variable only when there is an error occurred (like some of the function returned with -1).


1 Answers

perror and errno are only available if you link against the libc (-lc).

A "naked" syscall (without library support) usually returns in case of failure "the negative of a standard error code" (man syscall(2)). With a simple NEG you get the positive number of the error.

The error numbers can be found in the Linux source-files include/asm-generic/errno-base.h and include/asm-generic/errno.h.

The possible errors are described in the man-pages, e.g. man open(2). The name of a specific syscall can be figured out (with a bit of imagination) here. strace on programs that are known to work can be helpful.


I wrote an example showing how to build a list of "Pascal"-strings with the error messages and how to walk through that list:

DEFAULT rel

GLOBAL _start

SECTION .data

    non_existing_file db "bielefeld.txt",0

SECTION .text

_start:
    push rbp
    mov rbp, rsp
    and rsp, -16                ; Align 16

    mov rdi, non_existing_file  ; Pointer to null-terminated filename
    xor rsi, rsi                ; RD_ONLY
    mov rax, 2                  ; sys_open
    syscall                     ; Call Linux

    ; if no errorcode (EAX > -1 || EAX < -133) exit (and close)
    cmp eax, -1
    jg .done
    cmp eax, -133
    jl .done

    neg rax                     ; Get positive error number: RAX = Abs (RAX)
    mov rdi, rax                ; Argument for my_perror
    call my_perror              ; Output error message

    .done:
    leave
    xor edi, edi                ; Return 0
    mov eax, 60                 ; sys_exit
    syscall

;==================== my_perror ====================

SECTION .text

my_perror:                          ; ARG: RDI=errno
    push rbp
    mov rbp, rsp
    sub rsp, 16                     ; Aligning 16 though only one byte is needed

    ; No processing if wrong number
    test edi, edi
    jz .done
    cmp edi, 133
    ja .done

    ; Walk through the err_txt-list
    xor edx,edx
    mov rsi, err_txt
    .L1:
    lea rsi, [rsi+rdx]
    mov dl, [rsi]               ; Length of string
    add rsi, 1                  ; Pointer to string
    sub edi, 1
    jnz .L1

    mov edi, 1                  ; stdout
    mov eax, 1                  ; sys_write
    syscall                     ; call Linux

    mov byte [rsp], 0x0A        ; Linefeed
    mov rsi, rsp
    mov edx, 1
    mov edi, 1                  ; stdout
    mov eax, 1                  ; sys_write
    syscall                     ; call Linux

    .done:
    leave
    ret

SECTION .data

%MACRO DATA_ERR 1
    %strlen len %1
    db len, %1
%ENDMACRO

err_txt:

; /usr/src/linux-source-3.2/include/asm-generic/errno-base.h
DATA_ERR "Operation not permitted"                         ; EPERM             1
DATA_ERR "No such file or directory"                       ; ENOENT            2
DATA_ERR "No such process"                                 ; ESRCH             3
DATA_ERR "Interrupted system call"                         ; EINTR             4
DATA_ERR "I/O error"                                       ; EIO               5
DATA_ERR "No such device or address"                       ; ENXIO             6
DATA_ERR "Argument list too long"                          ; E2BIG             7
DATA_ERR "Exec format error"                               ; ENOEXEC           8
DATA_ERR "Bad file number"                                 ; EBADF             9
DATA_ERR "No child processes"                              ; ECHILD           10
DATA_ERR "Try again"                                       ; EAGAIN           11
DATA_ERR "Out of memory"                                   ; ENOMEM           12
DATA_ERR "Permission denied"                               ; EACCES           13
DATA_ERR "Bad address"                                     ; EFAULT           14
DATA_ERR "Block device required"                           ; ENOTBLK          15
DATA_ERR "Device or resource busy"                         ; EBUSY            16
DATA_ERR "File exists"                                     ; EEXIST           17
DATA_ERR "Cross-device link"                               ; EXDEV            18
DATA_ERR "No such device"                                  ; ENODEV           19
DATA_ERR "Not a directory"                                 ; ENOTDIR          20
DATA_ERR "Is a directory"                                  ; EISDIR           21
DATA_ERR "Invalid argument"                                ; EINVAL           22
DATA_ERR "File table overflow"                             ; ENFILE           23
DATA_ERR "Too many open files"                             ; EMFILE           24
DATA_ERR "Not a typewriter"                                ; ENOTTY           25
DATA_ERR "Text file busy"                                  ; ETXTBSY          26
DATA_ERR "File too large"                                  ; EFBIG            27
DATA_ERR "No space left on device"                         ; ENOSPC           28
DATA_ERR "Illegal seek"                                    ; ESPIPE           29
DATA_ERR "Read-only file system"                           ; EROFS            30
DATA_ERR "Too many links"                                  ; EMLINK           31
DATA_ERR "Broken pipe"                                     ; EPIPE            32
DATA_ERR "Math argument out of domain of func"             ; EDOM             33
DATA_ERR "Math result not representable"                   ; ERANGE           34
DATA_ERR "Resource deadlock would occur"                   ; EDEADLK          35

; /usr/src/linux-source-3.2/include/asm-generic/errno.h
DATA_ERR "File name too long"                              ; ENAMETOOLONG     36
DATA_ERR "No record locks available"                       ; ENOLCK           37
DATA_ERR "Function not implemented"                        ; ENOSYS           38
DATA_ERR "Directory not empty"                             ; ENOTEMPTY        39
DATA_ERR "Too many symbolic links encountered"             ; ELOOP            40
DATA_ERR "Operation would block"                           ; EWOULDBLOCK  EAGAIN
DATA_ERR "No message of desired type"                      ; ENOMSG           42
DATA_ERR "Identifier removed"                              ; EIDRM            43
DATA_ERR "Channel number out of range"                     ; ECHRNG           44
DATA_ERR "Level 2 not synchronized"                        ; EL2NSYNC         45
DATA_ERR "Level 3 halted"                                  ; EL3HLT           46
DATA_ERR "Level 3 reset"                                   ; EL3RST           47
DATA_ERR "Link number out of range"                        ; ELNRNG           48
DATA_ERR "Protocol driver not attached"                    ; EUNATCH          49
DATA_ERR "No CSI structure available"                      ; ENOCSI           50
DATA_ERR "Level 2 halted"                                  ; EL2HLT           51
DATA_ERR "Invalid exchange"                                ; EBADE            52
DATA_ERR "Invalid request descriptor"                      ; EBADR            53
DATA_ERR "Exchange full"                                   ; EXFULL           54
DATA_ERR "No anode"                                        ; ENOANO           55
DATA_ERR "Invalid request code"                            ; EBADRQC          56
DATA_ERR "Invalid slot"                                    ; EBADSLT          57
DATA_ERR "Resource deadlock would occur"                   ; EDEADLOCK   EDEADLK
DATA_ERR "Bad font file format"                            ; EBFONT           59
DATA_ERR "Device not a stream"                             ; ENOSTR           60
DATA_ERR "No data available"                               ; ENODATA          61
DATA_ERR "Timer expired"                                   ; ETIME            62
DATA_ERR "Out of streams resources"                        ; ENOSR            63
DATA_ERR "Machine is not on the network"                   ; ENONET           64
DATA_ERR "Package not installed"                           ; ENOPKG           65
DATA_ERR "Object is remote"                                ; EREMOTE          66
DATA_ERR "Link has been severed"                           ; ENOLINK          67
DATA_ERR "Advertise error"                                 ; EADV             68
DATA_ERR "Srmount error"                                   ; ESRMNT           69
DATA_ERR "Communication error on send"                     ; ECOMM            70
DATA_ERR "Protocol error"                                  ; EPROTO           71
DATA_ERR "Multihop attempted"                              ; EMULTIHOP        72
DATA_ERR "RFS specific error"                              ; EDOTDOT          73
DATA_ERR "Not a data message"                              ; EBADMSG          74
DATA_ERR "Value too large for defined data type"           ; EOVERFLOW        75
DATA_ERR "Name not unique on network"                      ; ENOTUNIQ         76
DATA_ERR "File descriptor in bad state"                    ; EBADFD           77
DATA_ERR "Remote address changed"                          ; EREMCHG          78
DATA_ERR "Can not access a needed shared library"          ; ELIBACC          79
DATA_ERR "Accessing a corrupted shared library"            ; ELIBBAD          80
DATA_ERR ".lib section in a.out corrupted"                 ; ELIBSCN          81
DATA_ERR "Attempting to link in too many shared libraries" ; ELIBMAX          82
DATA_ERR "Cannot exec a shared library directly"           ; ELIBEXEC         83
DATA_ERR "Illegal byte sequence"                           ; EILSEQ           84
DATA_ERR "Interrupted system call should be restarted"     ; ERESTART         85
DATA_ERR "Streams pipe error"                              ; ESTRPIPE         86
DATA_ERR "Too many users"                                  ; EUSERS           87
DATA_ERR "Socket operation on non-socket"                  ; ENOTSOCK         88
DATA_ERR "Destination address required"                    ; EDESTADDRREQ     89
DATA_ERR "Message too long"                                ; EMSGSIZE         90
DATA_ERR "Protocol wrong type for socket"                  ; EPROTOTYPE       91
DATA_ERR "Protocol not available"                          ; ENOPROTOOPT      92
DATA_ERR "Protocol not supported"                          ; EPROTONOSUPPORT  93
DATA_ERR "Socket type not supported"                       ; ESOCKTNOSUPPORT  94
DATA_ERR "Operation not supported on transport endpoint"   ; EOPNOTSUPP       95
DATA_ERR "Protocol family not supported"                   ; EPFNOSUPPORT     96
DATA_ERR "Address family not supported by protocol"        ; EAFNOSUPPORT     97
DATA_ERR "Address already in use"                          ; EADDRINUSE       98
DATA_ERR "Cannot assign requested address"                 ; EADDRNOTAVAIL    99
DATA_ERR "Network is down"                                 ; ENETDOWN        100
DATA_ERR "Network is unreachable"                          ; ENETUNREACH     101
DATA_ERR "Network dropped connection because of reset"     ; ENETRESET       102
DATA_ERR "Software caused connection abort"                ; ECONNABORTED    103
DATA_ERR "Connection reset by peer"                        ; ECONNRESET      104
DATA_ERR "No buffer space available"                       ; ENOBUFS         105
DATA_ERR "Transport endpoint is already connected"         ; EISCONN         106
DATA_ERR "Transport endpoint is not connected"             ; ENOTCONN        107
DATA_ERR "Cannot send after transport endpoint shutdown"   ; ESHUTDOWN       108
DATA_ERR "Too many references: cannot splice"              ; ETOOMANYREFS    109
DATA_ERR "Connection timed out"                            ; ETIMEDOUT       110
DATA_ERR "Connection refused"                              ; ECONNREFUSED    111
DATA_ERR "Host is down"                                    ; EHOSTDOWN       112
DATA_ERR "No route to host"                                ; EHOSTUNREACH    113
DATA_ERR "Operation already in progress"                   ; EALREADY        114
DATA_ERR "Operation now in progress"                       ; EINPROGRESS     115
DATA_ERR "Stale NFS file handle"                           ; ESTALE          116
DATA_ERR "Structure needs cleaning"                        ; EUCLEAN         117
DATA_ERR "Not a XENIX named type file"                     ; ENOTNAM         118
DATA_ERR "No XENIX semaphores available"                   ; ENAVAIL         119
DATA_ERR "Is a named type file"                            ; EISNAM          120
DATA_ERR "Remote I/O error"                                ; EREMOTEIO       121
DATA_ERR "Quota exceeded"                                  ; EDQUOT          122
DATA_ERR "No medium found"                                 ; ENOMEDIUM       123
DATA_ERR "Wrong medium type"                               ; EMEDIUMTYPE     124
DATA_ERR "Operation Canceled"                              ; ECANCELED       125
DATA_ERR "Required key not available"                      ; ENOKEY          126
DATA_ERR "Key has expired"                                 ; EKEYEXPIRED     127
DATA_ERR "Key has been revoked"                            ; EKEYREVOKED     128
DATA_ERR "Key was rejected by service"                     ; EKEYREJECTED    129
DATA_ERR "Owner died"                                      ; EOWNERDEAD      130
DATA_ERR "State not recoverable"                           ; ENOTRECOVERABLE 131
DATA_ERR "Operation not possible due to RF-kill"           ; ERFKILL         132
DATA_ERR "Memory page has hardware error"                  ; EHWPOISON       133
like image 167
rkhb Avatar answered Nov 15 '22 03:11

rkhb