-1

How does SVC (SWI) instruction works? Where it puts supevisor call id and other data? Where to get a list of all supervisor call ids, its parameters and return types?

Im tried to find that all in google but it shows only useless things and nothing about supervisor calls. Documentations also have too small amount of need data

TX3
  • 13
  • 1
  • 2
    SWI doesn't do copy a register anywhere. AFAIK, if the kernel wants to get the call number from the immediate, it has to actually decode the machine code at the exception address, which is why later Linux chose an ABI where the call number is passed in a register. So the value is still there when kernel code runs. – Peter Cordes Jun 27 '23 at 17:21
  • svc simply causes the event which is documented for each architecture. There are some bits in the svc instruction itself but who wants to parse an instruction? System calls are specific to the operating system, so for each operating system perhaps for each version of each operating system, there is a set of svc calls. Since each operating system can choose how to implement the system call one might use a register or few to indicate the system call and pass parameters for the call. So you need to be looking for linux version x arm architecture y system call interface or something like that – old_timer Jun 27 '23 at 18:41
  • or windows (version x) or some rtos or whatever your os is...even if some calls match assume that each os does their own thing – old_timer Jun 27 '23 at 18:41
  • It is much like a function call. Where is it documented what registers `ldmia` restores. Ie, it is a convention of the code. Each OS will use different numbers. Unless you document what OS it is, the 'id and data' are not defined. They are not part of the CPU. – artless noise Jun 27 '23 at 18:51
  • Is the number after the SVC instruction the address where the system retrieves data about the call ID and other information? – TX3 Jun 27 '23 at 19:06
  • 1
    Usually the id of the system call is passed as a parameter, i.e. data, rather than encoded within the instruction's immediate. Using data for the id allows more flexible implementations, i.e. shared code for system calls, whereas if a different imm were used for each one, you'd need more un-shareable code to make various different system calls. The ABI will usually pass the system call id in a register different from calling convention parameter registers, also to keep things easy for compiled code making system calls. You can get syscall #'s from something like https://arm64.syscall.sh/ – Erik Eidt Jun 27 '23 at 22:01

1 Answers1

2

I'll describe AArch64 here, but AArch32 is similar. I'll also take a typical example where the svc is invoked at EL0 ("user mode") and handled at EL1 ("kernel mode"). The authoritative reference for everything below is the Armv8-A Architecture Reference Manual (ARM), version I.a.

Unlike the x86 int instruction, the immediate operand to svc has no role in determining the vector to the exception handler. Instead, the vector is always obtained by taking the vector base address from the system register VBAR_EL1 and adding an offset determined by the type of exception and the exception level. See Table R_RYXCL in the ARM. In this case, since svc is a synchronous exception coming from a lower exception level using AArch64, the offset is 0x400.

Exception handling on ARM includes storing a "syndrome" code into ESR_EL1, and in the case of svc, the immediate operand is stored as the low 16 bits of the syndrome. See the description of svc at C6.2.365. The CPU itself doesn't do anything further with the operand value. So it is up to the operating system designer to determine how (or if) to use this value. Thus you have to consult the documentation for your operating system to see what, if anything, it does. Information on the calling conventions, register contents, return values, etc, would also be up to the OS to specify as part of its ABI, though most use some variation of the AArch64 Procedure Call Standard.

An OS ABI could be designed such that it uses this value to specify what service is to be performed. However, many OSes don't do this, and have the program specify the service with a system call number in one of the general-purpose registers instead. This is what Linux does; it expects the system call number to be passed in x8, and the immediate operand to svc is simply ignored. A table of the meaning of the different system call numbers for Linux, and the parameters they expect, can be found at https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/syscalls.md#arm64-64_bit. The actual behavior of each named system call (write, open, etc) is found in its man page.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82