Dudo mucho que el compilador sepa que es una llamada al sistema. Es mucho más probable que open
esté en una biblioteca en alguna parte y el código dentro de la biblioteca llame a la interfaz del kernel relevante.
La salida de montaje del programa simple:
#include <stdio.h>
int main (void) {
int fd = open("xyz");
return 0;
}
es (bits irrelevantes eliminados):
main:
pushl %ebp ; stack frame setup.
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $.LC0, (%esp) ; Store file name address.
call open ; call the library function.
movl %eax, 28(%esp) ; save returned file descriptor.
movl $0, %eax ; return 0 error code.
leave ; stack frame teardown.
ret
.LC0:
.string "xyz" ; file name to open.
Lo primero que notará es que hay una llamada-open
. En otras palabras, es una función. No hay un int 80
o sysenter
a la vista, que es el mecanismo utilizado para las llamadas al sistema adecuadas (en mi plataforma de todos modos, YMMV).
Las funciones de envoltura en libc son donde se realiza el trabajo real de acceder a la interfaz de llamada del sistema.
Un extracto de Wikipedia en system calls:
general, los sistemas proporcionan una biblioteca que se encuentra entre los programas normales y el sistema operativo, por lo general una implementación de la biblioteca de C (libc), tales como glibc. Esta biblioteca existe entre el sistema operativo y la aplicación, y aumenta la portabilidad.
En sistemas basados en exokernel, la biblioteca es especialmente importante como intermediario. En exokernels, las bibliotecas protegen las aplicaciones de usuario de la API kernel de muy bajo nivel y proporcionan abstracciones y administración de recursos.
Los términos "llamada al sistema" y "syscall" a menudo se usan incorrectamente para referirse a las funciones de biblioteca estándar C, particularmente aquellas que actúan como un contenedor para las llamadas al sistema correspondientes con el mismo nombre. La llamada a la función de biblioteca no causa un cambio al modo kernel (si la ejecución no estaba ya en modo kernel) y suele ser una llamada de subrutina normal (es decir, utilizando una instrucción de ensamblaje "CALL" en algunas ISA). La llamada al sistema real transfiere el control al núcleo (y depende más de la implementación que la llamada a la biblioteca que lo abstrae). Por ejemplo, fork
y execve
son funciones GLIBC que a su vez llaman a las llamadas al sistema fork
y execve
.
Y, después de un poco de búsqueda, la función __open
se encuentra en glibc 2.9 en el archivo io/open.c
, y weakref
'ed a open
.Si se ejecuta:
nm /usr/lib/libc.a | egrep 'W __open$|W open$'
se pueden ver allí:
00000000 W __open
00000000 W open
open también es llamada al sistema. No hay código para abrir en ninguna biblioteca. ¿Cómo se resuelve el compilador para la llamada abierta? –
No es así, consulte la actualización. – paxdiablo
Digamos, inserté mi propia llamada al sistema y compilé el kernel que no tiene la función de envoltura en libc. –