Upcoming Posts

Upcoming Posts....

Make your own partition magic software.
How to make an assembler.
What is booting?
Write a simple OS!

‎"I have no special talents. I am only passionately curious." - Albert Einstein

Saturday, June 9, 2012

VTABLE Table in C/C++

Non virtual functions get linked statically. I.e. their addresses along with machine code of ‘CALL’ assembly instruction are placed to make/resolve method call. However, to resolve virtual methods, compiler creates a table called VTABLE and puts address of all the virtual methods in it. With the help of this table, calls to appropriate method get resolved at runtime. Compiler places code to fetch the address of virtual method from VTABLE to make a call to the virtual method.

The VTABLE is created in the data segment, not on heap, at compile time (not at run time). Compiler creates only one VTABLE for a class containing virtual method (including inherited method) and all its object will have VPTR pointer variable pointing to the VTABLE. The VPTR variable is initialized in default constructor, copy constructor and assignment operator.

Thursday, May 31, 2012

Linux Programming Interfaces (or API)

There are two types of programming interfaces under Linux:

1) APIs for User Space Applications:

Linux provides API for user space applications (everything outside the kernel) called system calls. It is an interface between application and kernel.

Usually, we do not invoke system calls directly. Instead, we call wrapper methods like “exit()” provided by library like libc. For more information on system call and their implementations, please go through “System call” post.

2) APIs for Kernel Space Applications:

In order to make Kernel programming (writing modules/drivers) easier, Linux Kernel exports many methods including system call handlers. These methods are also called Kernel interface. To see these interfaces (exported symbols), you can run “cat /proc/kallsyms” command.

Example,

[root@linux ~]# grep sys_exit /proc/kallsyms
ffffffff810709f0 T sys_exit

“sys_exit” is an interface for kernel programmers which handle exit system call. From kernel module, we can directly call these system call handlers along with other kernel APIs.

Kernel application/programs in Linux are known as Kernel Module. These modules can be loaded and unloaded at runtime without rebooting the kernel. Once they get loaded into the memory, they become part of the kernel. Thus they can access all kernel exported methods directly.

Tuesday, April 24, 2012

Write your own Socket library in C/C++ for Linux

We have read so many things about invoking System Calls on Linux. Theories are useless unless we implement them :) (at least I believe). Thus Let's play with sockets by calling System/Kernel services directly. i.e. we will not use methods provided by C runtime libs. We will implement methods of POSIX Socket API like socket, bind etc.

Linux provides single system call called "sys_socketcall" for socket related operations. Its System call number is 102 (defined as macro __NR_socketcall in /usr/include/asm/unistd.h). Its protype defined in kernel is as follows:

long sys_socketcall(int call, unsigned long *args)

The fist parameter 'call' is an integer that identifies the specific operation to be performed. The possible values for call are defined in /usr/include/linux/net.h. Some of them are listem below:

#define SYS_SOCKET      1               /* sys_socket(2)                */
#define SYS_BIND        2               /* sys_bind(2)                  */
#define SYS_CONNECT     3               /* sys_connect(2)               */
#define SYS_LISTEN      4               /* sys_listen(2)                */
#define SYS_ACCEPT      5               /* sys_accept(2)                */

The second parameter 'args' is a pointer to an array of 'long' containing arguments for the operation.

Let's implement POSIX socket creation method "int socket(int domain, int type, int protocol)":

int my_socket(int domain, int type, int protocol)
{
long arg[3], sock = 0;

/*
   Copy 'domain', 'type' and 'protocol' in 'arg' array. This array will be passed to system call as parameter to kernel.
 */

arg[0] = domain;
arg[1] = type;
arg[2] = protocol;

/* 
long sys_socketcall(int call, unsigned long *args) ;

To call above system call, we would need to copy "__NR_socketcall" System call no. into eax register,  "SYS_SOCKET" socket operation 'call' code into ebx, and an array of 'long' containing 'domain', 'type', 'protocol' into ecx register.

The following code does the same thing. For more informaiton, find on google 'assembly using gcc' :).
*/

asm(
"int $0x80\n\t"  /* int 0x80 invokes Linux system call */
:"=a"(sock)   /* system call returns output in eax register, copy eax
                                     registers value into sock  */
:"a"(__NR_socketcall), "b"(SYS_SOCKET), "c"(arg)

/*
Above line passes "__NR_socketcall" System call no into eax register,
"SYS_SOCKET" socket operation 'call' code into ebx,
and an array of 'long' containing 'domain', 'type', 'protocol' into ecx register.
*/
); /* asm statement ends here*/

return sock; /* return socket FD*/
}

For the sake of simplicity, I haven't perfomed sanity check. While writing your own implementation, please do perform sanity check before invoking System call.

Similarly, you can define all the socket methods like bind, listen,accept, send etc and can make your own Socket library. Is not it simple? May be I have picked the simple one ;) to System Call simple.


Please leave your comments!!!

Thursday, April 19, 2012

How does 64bit Linux Kernel runs 32bit application?

I like questions which makes me think and challenge my technical ability. During a telephonic interview, interviewer asked me "How does 64bit Linux Kernel runs 32bit application?" How would you have answered this question? After taking couple of seconds, I said "That’s really a good question (was buying time J to think). Hmmm. I am not sure but I believe either 32bit C/C++ library or System call handler for 32bit will make adjustment, according to 64bit Data model, to the input/output parameters before passing them to the kernel ". Read further if you are curious to know the correct answer :):

Whenever System Call is invoked, the System Call handler method gets called. The handler validates input/output parameters and calls appropriate function which actually performs the requested operation. I.e. the handler is a kind of wrapper over actual method which processes the request.

64 bit Linux Kernel supports LP64 data model which means "long" and "pointers" will be of 64bit. I.e. The size of "Long" or "Pointer" data types should be of 64bit when a 64bit application invokes System Calls. This causes problem for 32bit applications as they consider "long" and "pointers" of 32 bit.

Because of the above mentioned difference, the 64bit kernel has to have separate system call handler method 1) for 64 bit System calls and 2) for 32bit System calls. Please note that the kernel maintain two versions of core methods which actually processes requests like opening a file. Let’s look the below picture:




The core methods of 64bit kernel expect "long" and "pointers" data types to be of 64bit size. This is ok for 64bit System Calls. However, 32bit system call has to make 32bit "long" and "pointers" types to 64bit "long" and "pointers" before passing them to kernel’s core methods. For this conversion/adjustment, Linux Kernel uses a compat (compatibility) Layer. This layer has to be the part of kernel.

In short, it is the System call handler (not C/C++ library) for 32bit which makes adjustment/conversion, according to 64bit Data model, to the input/output parameters before passing them to the kernel

Please leave comment to improve my writing skillsJ.

Wednesday, April 18, 2012

Invoking System calls on Linux

It is not possible to directly link (using any compiler) user-space applications with kernel space. For security and reliability reasons, the user-space applications must not be allowed to directly execute kernel code or manipulate kernel data. Instead, the kernel must provide a mechanism by which a user-space application can "signal" the kernel that it wishes to invoke a system call. The application can then trap into the kernel through this well-defined mechanism, and execute only code that the kernel allows it to execute. The exact mechanism varies from architecture to architecture.
According to x86-32 Linux System Call convention (on the i386 architecture), Linux System-call is done via "int 0x80" instruction and the following registers are used to pass parameters to kernel:
eax -  System call number.bx, ecx, edx, esi, edi, ebp - Used for passing 6 parameters.If there are more than six arguments, ebx must contain the memory location where the list of arguments is stored. Return Values depends on system calls. Most system calls uses EAX to return values, but not for all. If it is not there, you need further research :).
According to x86-64 Linux System Call convention, Linux System-call is done via the "syscall" instruction and the following registers used to pass parameters to kernel:
eax -  System call number.rdi, rsi, rdx, r10, r8 and r9. - Used for passing 6 parameters.
Please note that the kernel destroys registers rcx and r11. Thus you may need ot take care of the values stored rcx and r11.
Return Values depends on system calls. Most system calls uses EAX to return values, but not for all. If it is not there, you need further research :).
There are three ways to invoke System call:
1. Invoking System Calls indirectly by calling C/C++ standard methods:
exit_c.c:
void main()
{
exit(6); /* to exit current process with 6 as exit code */
}
gcc exit_c.c
./a.out
Here, we are calling C/C++ "exit()" method to terminate process with 6 as exit code. This "exit()" method present in C/C++ library will make appropriate system call to terminate the process. Since we are calling standard method here. This program will be portable and can work on all the platforms.
2. Invoking System Calls indirectly by calling C wrapper methods for system calls:
exit_ind_sys.c:
void main()
{
syscall(1,6); /* 1 is System call number for exiting program and 6 is the user defined exit status code */
}
gcc exit_ind_sys.c
./a.out
Here, "syscall()" is a GNU C library function. It is harder to use and less portable than C functions like "exit()", but easier and more portable than coding the system call in assembler instructions.
3. Invoking System Calls directly by writting assembly code:
exit_as.c:
void main()
{
asm(
"movl $1, %eax\n\t" /* 1 is System call number for exiting program */
"movl $6, %ebx\n\t" /* 6 is the user defined exit status code */
"int $0x80\n\t"     /* */
);
}
gcc exit_as.c
./a.out
Here, we are calling System API directly by executing "int $0x80" instruction from program itself. This makes it non-portable code. It will work with Linux on Intel machines only.
Getting System call numbers and their parameters:
System call numbers are defined in "/usr/include/asm/unistd.h" header file as "#define _NR_exit 1". Parameters to each system call is defined in "syscalls.h" file as "asmlinkage long sys_exit(int error_code);".
[root@localhost linux]# find / -name syscalls.h/usr/src/kernels/2.6.18-8.el5-i686/include/linux/syscalls.h


Linux Header Files:



/usr/include/asm/*.h
The Linux API ASM Headers
/usr/include/asm-generic/*.h
The Linux API ASM Generic Headers
/usr/include/drm/*.h
The Linux API DRM Headers
/usr/include/linux/*.h
The Linux API Linux Headers
/usr/include/mtd/*.h
The Linux API MTD Headers
/usr/include/rdma/*.h
The Linux API RDMA Headers
/usr/include/scsi/*.h
The Linux API SCSI Headers
/usr/include/sound/*.h
The Linux API Sound Headers
/usr/include/video/*.h
The Linux API Video Headers
/usr/include/xen/*.h
The Linux API Xen Headers
                   



Reference:
http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64
http://asm.sourceforge.net/syscall.html

Tuesday, April 17, 2012

What is System Call?

The system call is the fundamental interface between an application and the operating system's kernel. It is a way to requests a service like creating/opening file from the kernel.

1. System calls are not normal method calls. No libraries or header files are supplied by the OS. i.e. stdio.h is not provided by the OS. It's provided by the C/C++ language.
2. Usually System calls are not invoked directly, but rather via wrapper functions in glibc (or perhaps some other library).
3. Input or output parameters to System calls are copied to registers or pushed onto stack.
4. System calls are OS dependent. i.e. Two operating systems may not have same System calls.

Few System calls are as follows:

Process Control - load/execute/create/terminate process etc.
File management - create/delete/open/close/read/write file etc.
Device Management - request/release/read/write devices.



It is not possible to directly link (using any compiler) user-space applications with kernel space. For reasons of security and reliability, user-space applications must not be allowed to directly execute kernel code or manipulate kernel data.


Instead, the kernel must provide a mechanism by which a user-space application can "signal" the kernel that it wishes to invoke a system call. The application can then trap into the kernel through this well-defined mechanism, and execute only code that the kernel allows it to execute. The exact mechanism varies from architecture to architecture.


Typically, System calls are implemented as software interrupt or trap. Nowadays, additional techniques like SYSCALL/SYSENTER, SYSRET/SYSEXIT (the two mechanisms were independently created by AMD and Intel, respectively), is being used.

Generally, System calls are not invoked directly, but rather via wrapper functions in glibc (or perhaps some other library). Why? Because System calls are OS dependent. Making direct System calls from the program will make it non-portable. Instead, we should call wrapper methods/API provided by Standard C/C++ libs.


Let's take an example, you'd like to create a new file and want to write your name to the file. You'll write the following C program:

#include
#include "input.c"

int main(void)
{
char name[64] = "Dew Kumar";
 FILE *playerdata;

playerdata = fopen(name, "W+"); /*create the new file*/
fgets(name,buffer,playerdata); /*write the players name to the file*/
fclose(playerdata); /*close the file*/
}

Here, fopen(), fgets() and fclose() are the library method/API which calls System call to open/write/close files.

Reference: http://en.wikipedia.org/wiki/System_call

Tuesday, March 27, 2012

C/C++ Data Model (32/64 Bit)

A machine dependent high level language provides several data types like char, int and long. However, Compilers/Languages are not free to decide the size of the data types. The reason is that the Language has to call OS's system API providing expected inputs of data. Thus the size of any data type provided by compiler must match with the data types expected by OS and its System API. Otherwise, System call will fail with some error and will not get expected result. Isn't it?

Let's consider a system call which expects first argument as 'int' (4 byte) and second argument as 'char' (1 byte) as input. In order to call this API, the compiler have to have a 'int' data type of 4 byte and a 'char' data type of 1 byte to call that system API. Isn't it? Suppose, the compiler has 'int' data type of 1 byte and 'char' of 4 byte. Now when the call to the OS API is made, it will fail as it is expecting first argument as 'int' (4 byte) and second argument as 'char' (1 byte) data. Isn't it? It is obvious that API will fail with an error. In such case, as a workaround, we can pass an 'int' (as its size if 1 byte in our compiler) as fist argument and a 'char' as second argument. Doing this will be a big issue programing issue and it will cause any confusions and issues. That's the reason, compiler's data type must match with the data types chosen by the Operating System.

There will be many more issues if the size of any data type (provided by compiler) is not same as the OS data types. To avoid such issues, data models which specify the size of each data type are introduced and standardized. The compiler is enforced to follow data model chosen by the Operating System.

Every application and every operating system has an abstract data model. Many applications do not explicitly expose this data model, but the model guides the way in which the application's code is written.

The table below details the data types of several data models for comparison purposes.

Data model

   char
short
(integer)
Int
Long
(integer)
long long
pointer/
size_t
Sample operating systems
LP32
 8
 16
 16
 32

 32
Win-16, Apple Macintosh
ILP32
 8
 16
 32
 32

 32
32-bit UNIX
LLP64/
IL32P64
 8
16
32
32
64
64
Microsoft Windows
(X64/IA-64)
LP64/
I32LP64
 8
16
32
64
64
Most 64 bit Unix and
Unix-like
systems,
e.g. Solaris,
Linux, and
Mac OS Xz/OS
ILP64
 8
16
64
64
64
HAL Computer Systems port of
Solaris to SPARC64
SILP64
 8
64
64
64
64

Many 64-bit compilers today use the LP64 model (including Solaris, AIXHP-UX, Linux, Mac OS XFreeBSD, and IBM z/OS native compilers). Microsoft's Visual C++ compiler uses the LLP64 model.

Please note that the size of ’long long’ is 64 bit on 32 bit and 64 bit machine/OS. In the C99 version of the C programming language and the C++11 version of C++, a ‘long long’ type is supported that doubles the minimum capacity of the standard long to 64 bits. This type is not supported by compilers that require C code to be compliant with the previous C++ standard, C++03, because the ‘long long’ type did not exist in C++03. Microsoft Windows VC++ supports it. However, some compilers may not support it.


References:
http://en.wikipedia.org/wiki/64-bit
http://www.unix.org/whitepapers/64bit.html

Wednesday, March 21, 2012

Relationship between high level language data type with the processor's Data type

The size of any data type in any high level language like C/C++ has no direct relationship with the processor's data type. The size of any data type is defined by the language/compiler and it is implementation specific. Each data type is implemented in terms of data type supported by the processor.

Let's take Intel 8086 processor (16 bit) as an example, its instruction set supports following data types:

   Length | Size Name
  ---------|------------
   8-bit   | byte
   16-bit | word

It means, you can perform operations on 1/2 byte (8/16 bit) data. The Intel 8086 processor has no support for 4 byte (32 bit) data. You won't find any 8086 instruction which can perform operation on 4 byte (32 bit) data.

Now let's see the C data types and their sizes:

   Type              | Length | Range
  ------------------|----------|-----------------------------------------
   unsigned char |  8 bits  |                 0 to 255
   char              |  8 bits  |              -128 to 127
   enum            | 16 bits |           -32,768 to 32,767
   unsigned int   | 16 bits |                 0 to 65,535
   short int        | 16 bits |           -32,768 to 32,767
   int                | 16 bits |           -32,768 to 32,767
   unsigned long | 32 bits |                 0 to 4,294,967,295
   long              | 32 bits |    -2,147,483,648 to 2,147,483,647
   
Signed/unsigned Char data type of C/C++ is implemented as 'byte' data type of processor and other 16 bit data types like 'int', 'enum' etc are implemented as 'word' data type of processor. Now the question arises how can compiler support 32 bit data like 'long' on a processor (intel 8086) which doesn't support 32 bit arithmatics/operations ?

The answer is very simple :), the 32 bit data type like 'long' is implemted in terms of two 'word' data types of processor. Compilers implement 32 bit arithmetic operations by using 16 bit arithmetic operations provided by the processor.

Mapping each C/C++ data types with processor's data type doesn't mean that the size of any C/C++ data type will be determined by the processor. The data type of a machine dependent high level language is implemented in terms of processor's data type. It is the language and compiler which provides these data types. Thus the size of these data types will oviously be specified by the language/compiler.

Read Data models for more information on this.

Tuesday, February 28, 2012

Virtual Machine Implementation

Can application software run an operating system? Let me put it in other way, how can ‘VMware’ application executes/loads operating system like Linux? Curious to know, be patient and read this article:

Let me start with the computer fundamental to get you in the context of virtual machine:

Hardware – Computer consists of hardware's like processor, RAM, Hard disk, monitor, keyboard and motherboard which contains chips like BIOS, System timer chip 8054, Interrupt controller 8259 etc.

Software – Operating system (OS) and other software’s like compiler, MS office etc are nothing but a binary file or a set of binary files which contain machine level instructions or opcode (Operation code).

When OS gets loaded into the memory, processor reads instructions and performs operations accordingly. Anything (any machine/person/software) which can follow the instruction mention in binary file(s) can load/execute OS. Isn’t it? Let’s take an example of processor:

Processor: It has several registers used to hold values. Few registers tell processor where the code segment and where the data is in the memory. Using these special registers, processor executes instructions and completes its job. Suppose, the processor reads ‘89D8’ instruction (equivalent to MOV AX,BX assembly code), it will copy the content of BX register into AX register. Similarly, the opcode ‘A0 F4 C4’ (equivalent to MOV AL, [34F4] assembly code) will copy content stored at “34F4” memory address in data segment into AL register.

This is how the processor makes machine and OS usable. Here, you can think that processor is doing nothing but just following the instruction written in OS binaries files. Right?

Now think, can’t we write a program which can behave exactly like a processor? We can write a class to represent a processor and write methods which will perform operations as processor does. The program will work like a processor. Isn’t it? Note that the physical processor is not executing these instructions, a program is doing that. So we can call this program, a ‘virtual’ processor. Can’t we?

Similarly, we can write programs for implementing virtual RAM, Hard disk, monitor, keyboard and motherboard which contains chips like BIOS, System timer chip 8054, Interrupt controller 8259 etc. Combining all these virtual devices will make a virtual machine software like VMWare. Stay tuned for more information on implementation!!!

I hope you’d have enjoyed reading this article. Post your feedback and help me in improving my writing skills/style!

Wednesday, February 15, 2012

How is 'this' pointer passed to the member method?

We know the 'this' pointer points to the object being worked on. All the member methods access object's data using 'this' pointer. C++ Standards doesn't say anything about how to pass 'this' pointer to the Member function. It depends on compiler's calling convention implementation. There are two ways to pass 'this' pointer to the member methods:

1. Pass 'this' pointer to method as argument by pushing it on stack. GCC/CC uses this mechanism.

For example, you can consider that compiler will teat 'void test::display()' method as 'void test::display(test *this)'.

2. Copy 'this' pointer on a register (ECX register is used by VC++). Microsoft VC++ uses this mechanism to provide 'this' pointer to the member methods.

test a;
a.compile_time_binding_method();
     lea ecx,[a] // Address of object 'a' is getting copied in ECX register
     call test::compile_time_binding_method (41118Bh)

You can refer 'Calling Convention' for more information.

Thursday, January 12, 2012

Why does C++ not allow overloading ‘.’ , ‘:*’ , ‘::’ and ‘?:’ operators?

Stroustrup’s wanted to allow programmers to use all the operators with user defined data types as well. Thus he added operator overloading as feature in C++ so that programmers can define functionality of operators for user defined data types. A restriction is that the operators like ‘.’ , ‘:*’ , ‘::’ and ‘?:’ are not allowed for overloading. These operators are not meant to use with any data types. These are introduced to use language’s features like:

“.” Direct member access operator is used to access member variable/function.

“:*” De-reference pointer to class member operator is used to De-reference pointer to class member.

“::” Scope resolution operator is used to access global variable and define method outside class.

“?:” Conditional operator is like if-else condition. Why do we need to overload it.

“Sizeof” operator is used get size of an object. It can’t be overloaded because built-in operations such as incrementing a pointer into an array implicitly depend on it. Consider:

                X a[10];
                X* p = &a[3];
                X* q = &a[3];
                p++;   // p points to a[4]
                          // thus the integer value of p must be
                          // sizeof(X) larger than the value of q

Thus, sizeof(X) could not be given a new and different meaning by the programmer without violating basic language rules.

As above operators are close to the core of the language, allowing overloading of these operators can cause many problems/confusions without any benefits (“->” operator is allowed to overload to make a smart pointer class).

Reference: The Design and Evolution of C++ by Bjarn Stroustrup