Loading

Paste #pey9aijbg

  1. ;---{  LINUX  }------------------------------------------------------------------------------------------------------------
  2.  
  3. ; According to A.2 of AMD64 SysV ABI Draft 0.99 May 11,2009, an interface between libC and Linux kernel is as follows:
  4. ; - syscall number is passed in RAX
  5. ; - from 0 up to 6 int64 arguments, passed in RDI, RSI, RDX, R10, R8, R9
  6. ; (note that differs from app/app and kernel/kernel interface, which is RDI, RSI, RDX, RCX, R8, R9)
  7. ; - RCX and R11 is destroyed by kernel
  8. ; (app/app destroys all passable, and RAX, R10, R11, not sure about kernel/kernel)
  9. ; - on return, RAX contains a result, -1..-4095 is -errno
  10. ; So, let's implement this in variadic parametrised code generator (7 variants in one pseudo-operation):
  11.  
  12. ; helper: smart mov register <- X, some assembly optimizing here
  13. %macro smartmovreg  2.LINUX_SYSCALL_MACRO.listing
  14.  
  15. %ifnum %2 ; source is numeric? 
  16.   %if %2 == 0 ; optimize for source zero
  17.     xor %1,%1
  18.   %else    
  19.     mov %1,%2   ; mov immediate, either 32 or 64 sized <--- zde zvazit silnejsi optimalizaci pro immediate
  20. ; celou logiku se signed extend jsem skrtnul, pac se to chovalo divne. promyslim to pozdeji toto je dostatecne zatim
  21.   %endif
  22. %else      
  23.   %ifidni %1,%2 ; optimize for source lexikographically same as target (==we already passed in the "correct" one)
  24.     ; nothing here, produce empty code
  25.   %else         ; otherwise generate some kind of a mov, from a register or Q-sized storage
  26.     mov %1,%2   ; possibly with extended addressing modes
  27.   %endif
  28. %endif
  29.  
  30. %endmacro
  31.  
  32. ; Linux system call pseudo-operation, user
  33. %macro  LINUX   1-7.LINUX_SYSCALL_MACRO.listing
  34.  
  35. %if (%0-1) != Linux.sys_%1.args   ; Issue a warning on suspectly wrong invocation, either a usage error or bug in declarator
  36.   %assign %%params Linux.sys_%1.args
  37.   %defstr %%message Linux syscall (%1): number of passed arguments (%0) does not correspond to syscall declarator (1+%%params)
  38.   %warning %%message
  39. %endif
  40.  
  41. ; param registers ordered by ABI64 specification
  42. %if %0 > 6
  43.     smartmovreg r9,%7
  44. %endif
  45. %if %0 > 5
  46.     smartmovreg r8,%6
  47. %endif
  48. %if %0 > 4
  49.     smartmovreg r10,%5
  50. %endif
  51. %if %0 > 3
  52.     smartmovreg rdx,%4
  53. %endif
  54. %if %0 > 2
  55.     smartmovreg rsi,%3
  56. %endif
  57. %if %0 > 1
  58.     smartmovreg rdi,%2
  59. %endif
  60.     mov rax,Linux.sys_%1
  61.     syscall
  62. ; after a syscall, we received something in rax. here we detect if user wants to receive errno to her store for reuse,
  63. ; which is default if previously issued an ABI64 Process declarator (a singleton macro)
  64. %ifnum Process.errno.automagic
  65. ; user can control this functionality throughout assembly unit by %assign Process.errno.automagic to 0
  66. ; so a particular syscall invocation could be used in some raw code without this automagic
  67. %if Process.errno.automagic > 0
  68.     mov [Process.errno],rax
  69. %endif 
  70. %endif
  71.  
  72. %endmacro
  73.