Multiple system calls

I finally found the answer to little conundrum [1]. But first, a bit of a recap—the code for __getpid (the function that acually does the system call) that I presented:

>
```
0804e380 <__getpid>:
804e380: b8 14 00 00 00 mov $0x14,%eax
804e385: cd 80 int $0x80
804e387: c3 ret
```

That was generated from the output from objdump, and in order to get that, I had to compile the program using gcc -g -static -o t1 t1.o t1a.o, but note the -static bit there. Normally, such routines are part of a shared library that aren't included in the final executable, but by adding -static when compiling, the routines in the standard libraries are included in the final result. And had I run the statically compiled version, I would have seen that the code that calls the system supplied __getpid() would have taken 11 minutes to run.

What bit of code was I actually testing?

>
```
(gdb) disassemble __getpid
Dump of assembler code for function getpid:
0x00820730 <getpid+0>: mov %gs:0x4c,%edx
0x00820737 <getpid+7>: test %edx,%edx
0x00820739 <getpid+9>: mov %edx,%eax
0x0082073b <getpid+11>: jle 0x82073e <getpid+14>
0x0082073d <getpid+13>: ret
0x0082073e <getpid+14>: jne 0x820752 <getpid+34>
0x00820740 <getpid+16>: mov %gs:0x48,%eax
0x00820746 <getpid+22>: test %eax,%eax
0x00820748 <getpid+24>: nop
0x00820749 <getpid+25>: lea 0x0(%esi),%esi
0x00820750 <getpid+32>: jne 0x82073d <getpid+13>
0x00820752 <getpid+34>: mov $0x14,%eax
0x00820757 <getpid+39>: call *%gs:0x10
0x0082075e <getpid+46>: test %edx,%edx
0x00820760 <getpid+48>: jne 0x82073d <getpid+13>
0x00820762 <getpid+50>: mov %eax,%gs:0x48
0x00820768 <getpid+56>: ret
0x00820769 <getpid+57>: nop
0x0082076a <getpid+58>: nop
0x0082076b <getpid+59>: nop
0x0082076c <getpid+60>: nop
0x0082076d <getpid+61>: nop
0x0082076e <getpid+62>: nop
0x0082076f <getpid+63>: nop
End of assembler dump.
```

Ah! That makes more sense then!

It's basically checking to see if the getpid() system call has been made, and if not, call it once, then cache the value for later calls to this routine. You also won't notice an int $80 here, but that's because the shared library version of __getpid() uses a different method of making a system call [2] than the traditional int $80, although the older method is still supported, which is why I suspect the static version of the system libraries use int $80 to make system calls—to support older systems that might not support the newer system call mechanism.

[1] /boston/2007/11/30.1

[2] http://manugarg.googlepages.com/systemcallinlinux2_6.html

Gemini Mention this post

Contact the author