C++ Essentials Training
5-day session

Overview
Understanding principles of Object Oriented Programming Overview
Understanding the structure of a c++ program
Understanding Polymorphism
Understanding UML modeling
Practical labs with GNU g++ compiler
Duration
Three days - 40 hours (8 hours a day)
50% of lecture, 50% of practical labs.

Trainer
Audience
Professional Software developers
People supporting large scale products.
Prerequisite
Knowledge of C programming
In particular, participants must be familiar with creating and dealing with
complex data types and structures, with pointers to such symbols, as well as
with function pointers.
Advance C training agenda is available at
http://www.minhinc.com/training/c/advance-c-slide.php
and can be downloaded from
http://www.minhinc.com/training/advance-c-slide.pdf

Knowledge of Object Oriented Concepts
Oops concept like Abstraction, Inheritance, Polymorphism would help.

Setup
Linux machine with GNU g++ compiler installed.
© www.minhinc.com
p1
Lecture
Lecture session will be course content presentation through the trainer.
Any source code example related to the topic will be demonstrated, it would
include executing the binaries.
Complete lecture material can be downloaded from
http://www.minhinc.com/training/advance-cpp-slides.pdf
Labs
Labs session would be completely hands on session where each example
(with example data and execution instruction) would be provided to the
students. Students can verify their results with the results provided in
the material.
Day 1 Morning

© www.MinhInc.com
p2
Day 1 Afternoon

     Lab
Day 2 Morning

Day 2 Afternoon

     Lab
© www.MinhInc.com
p3
Day 3 Morning

Day 3 Afternoon

     Lab
Day 4 Morning

© www.MinhInc.com
p4
Day 4 Afternoon

     Lab
Day 5 Morning

Day 5 Afternoon

© www.MinhInc.com
p5
     Lab
C++ Essentials
C++ Essenstials- Training Course
Minh, Inc.
DISCLAIMER

Text of this document is written in Bembo Std Otf(13 pt) font.

Code parts are written in Consolas (10 pts) font.

This training material is provided through Minh, Inc., B'lore, India
Pdf version of this document is available at http://www.minhinc.com/training/advance-cpp-slides.pdf
For suggestion(s) or complaint(s) write to us at sales@minhinc.com

Document modified on May-15-2021 

Document contains 97 pages.
 
Day 1 Morning

  1. Introduction

  
 
             Stages of Program Development    |
                                              |
                                              v
                                   ----------------------
                                   | Architecture design|
                                   ----------------------
                                              |
                                              v
                                   ----------------------
            ---------------------->| Detailed design    |
            |                      ----------------------
            |                                 |
    -------------------                       v
    |  Redefine design|             ---------------------
    -------------------      ------>| Edit source files |
            ^                |      ---------------------
            |                |                |
            |                |                v
            |                |      ----------------------
            |                |      | Compile source file|
            |                |      ----------------------
            |                |                |
            |                |                v
            |                |       --------------------
            |                |       | Link Object files|
            |                |       --------------------
            |                |                |
            |                |                v
            |                |       ---------------------
            |                |       | Test and debug    |
            |                |       | executable program|
            |                |       ---------------------
            |                |                |
            +---------------------------------+ 
Architecture of c program
Function consists of header and body
 - Header contains preprocessor statements and class declarations (except template inclusion case where source is also included)
 - Body, enclosed in {brackets} contains statements, each terminated by semicolon
 
One function must be one called main()
 - C start up code calls main function as the entry point in the program.
 
Global variables are initialized prior the entry to main function.
 
Program execution starts in main, and progresses, statement by statement, until the last statement in main is completed
 
Definition of variable class and functions put in source file.
A source file contains definition of variable and functions.
 
<<source.c>> 
extern int i; // declaration
int func(); // declaration
int i=10;//declaration and definition
int func(){//definition
} 
 
Compiling one source file needs only declarations of the variable and the function be visible. Definition is not required while generating object file.
  
$ cat source.c
#include <stdio.h>
 
int func();
int main(){
func();
return 0;
} 
© www.minhinc.com
p6
$ g++ -c source.c -o source.o <-- compiling without definition
$ nm source.o
                 U _Z4funcv <--- U is undefined
                 U __gxx_personality_v0
0000000000000000 T main 
  
Day 1 Morning
  1. Introduction
 
Header contains constants, macros, system wide global variables, preprocessor
statements and declarations.
 
Header file is included with #include
example
  
$ cat header.h
#ifndef HEADER_H
#define HEADER_H
#include <stdio.h>
const int i=10;
extern int j;
struct A{
};
void put_s(const char*);
#endif
 
$cat source1.c
#include "header.h"
void put_s(const char *cp){
printf("puts %s
",cp);
}
 
$cat source2.c
#include "header.h"
int j=15;
 
$cat main.c
#include "header.h"
int main(int argc, char *argv[]){
puts("hello world");
printf("j %d
",j);
return 0;
}
 
$ g++ source1.c source2.c main.c -o headersource
$ ./headersource
hello world
j 15 
  
Day 1 Morning
  1. Introduction
 
A file that contains compiled code is known as an object file. Compiler creates object file which is binary file.  It is of three types
 
a) Relocatable file
This type of object file contains data and code that can be linked together with other relocatable files to produce an executable binary or a shared object file. It is similar as the .o file produced when we compile a code the following way :
  
$gcc -Wall -c test.c -o test.o 
© www.minhinc.com
p7
So the test.o produced after the operation above would be a relocatable file.
  
$ nm mathoperation.o
 
0000000000000000 T add
0000000000000027 T div
                 U fixit <-- Undefined
0000000000000014 T mul
 
$ objdump -x mathoperation.o 
  
mathoperation.o:     file format elf64-x86-64
mathoperation.o
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
 
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000005a  0000000000000000  0000000000000000  00000040  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  0000009c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  0000009c  2**2
                  ALLOC
  3 .comment      0000002e  0000000000000000  0000000000000000  0000009c  2**0
                  CONTENTS, READONLY
  4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000ca  2**0
                  CONTENTS, READONLY
  5 .eh_frame     00000078  0000000000000000  0000000000000000  000000d0  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 mathoperation.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     F .text	0000000000000014 add
0000000000000014 g     F .text	0000000000000013 mul
0000000000000027 g     F .text	0000000000000033 div
0000000000000000         *UND*	0000000000000000 fixit
 
RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
000000000000004d R_X86_64_PC32     fixit-0x0000000000000004
 
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE
0000000000000020 R_X86_64_PC32     .text
0000000000000040 R_X86_64_PC32     .text+0x0000000000000014
0000000000000060 R_X86_64_PC32     .text+0x0000000000000027 
  
$ cat mathoperation.c
 
void fixit(int,int);
int add(int a,int b){
return a+b;
}
int mul(int a,int b){
return a*b;
}
int div(int a,int b){
if (b=0)fixit(a,b);
return a/b;
} 
 
b) Shared object file
This type of object file is used by the dynamic linker to combine it with the executable and/or other shared object. It is similar as the .so file produced when the code is compiled with the -fPIC (position independent code) flag in the following way :
  
$gcc -c -Wall -Werror -fPIC shared.c -o shared.o
$gcc -shared -o libshared.so shared.o 
 
A shared object file libshared.so is produced as output.
 
example. 
$gcc -c -fPIC mathoperation.c -o mathoperation.o
 
$ nm mathoperation.o
0000000000000000 T add
0000000000000027 T div
                 U fixit
                 U _GLOBAL_OFFSET_TABLE_ <- relocating table
0000000000000014 T mul
 
$ gcc -c -fPIC mathoperation.c -o mathoperation.o
$ gcc -shared -o libmathoperation.so mathoperation.o
$ ldd libmathoperation.so
 
	linux-vdso.so.1 =>  (0x00007fffbd5fe000)
	libc.so.6 => /lib64/libc.so.6 (0x00007ffd916b4000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ffd91c8b000)
 
$ nm libmathoperation.so 
  
0000000000000708 T add
0000000000201030 B __bss_start
0000000000201030 b completed.6333
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000000620 t deregister_tm_clones
000000000000072f T div
0000000000000690 t __do_global_dtors_aux
0000000000200e00 t __do_global_dtors_aux_fini_array_entry 
© www.minhinc.com
p8
0000000000200e10 d __dso_handle
0000000000200e18 d _DYNAMIC
0000000000201030 D _edata
0000000000201038 B _end
0000000000000764 T _fini
                 U fixit
          <--------- Undefined
00000000000006d0 t frame_dummy 0000000000200df8 t __frame_dummy_init_array_entry 0000000000000840 r __FRAME_END__ 0000000000201000 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__ 00000000000005b8 T _init w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 0000000000200e08 d __JCR_END__ 0000000000200e08 d __JCR_LIST__ w _Jv_RegisterClasses 000000000000071c T mul 0000000000000650 t register_tm_clones 0000000000201030 d __TMC_END__
 
 
c) Executable file
This type of object file is a file that is capable of executing a program when run.
  
$ gcc -Wall test.c -o test 
Tool - objdump, nm
 
Example -
<<main.c>> 
#include "sample.h"
int main(int argc, char *argv[]){
struct fraction frtn;
frtn.numerator=12;
frtn.denominator=5;
func(&frtn);
return 0;
} 
 
<<sample.c>> 
#include <stdio.h>
#include "sample.h"
void func(struct fraction *f){
printf("value %d
",f->numerator/f->denominator);
} 
 
<<sample.h>> 
#ifndef SAMPLE_H
#define SAMPLE_H
struct fraction {
int numerator;
int denominator;
};
void func(struct fraction *f);
#endif 
 
$ objdump -r sample.o 
sample.o:     file format pe-i386
 
RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
0000001b dir32             .rdata
00000020 DISP32            _printf
 
 
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET   TYPE              VALUE
00000020 DISP32            .text 
 
 
$ nm sample.o 
00000000 b .bss
00000000 d .data
00000000 r .eh_frame
00000000 r .rdata
00000000 r .rdata$zzz
00000000 t .text
00000000 T _func
          U _printf 
 
$ ldd a.out 
linux-vdso.so.1 =>  (0x00007fffffbfe000)
libc.so.6 => /lib64/libc.so.6 (0x00007f96f51ee000)
/lib64/ld-linux-x86-64.so.2 (0x00007f96f55c3000) 
  
© www.minhinc.com
p9
Day 1 Morning
  1. Introduction
 
Declaration - Asserts the existence of a variable, function or type defined elsewhere in the program. A variable may be declared by preceding its type with the keyword extern.
  
int a; // just declaration
void func();//just declaration 
 
c++ 
int a // declaration and definition
extern a // declaration 
 
- Declaration can be made multiple times.
 
Definition - Allocates storage for a variable of a specified type and  optionally initializes the variable.
  
int a=10; //declaration and definition
void func(){// declaration and definition
} 
 
- Definition must be only once.
- How are declarations written so that variables are properly declared during compilation?
- How are declarations arranged so that all the pieces will be properly connected when the program is loaded?
- How are declarations organized so there is only one copy?
- How are external variables initialized?
  
Day 1 Morning
  1. Introduction
  
---------------  ---------------  --------------- ---------------
|source file  |  | source file |  | source file | | source file |
---------------  ---------------  ---------------  --------------
      |                 |                |               |
      v                 v                v               v
---------------  ---------------  --------------- ---------------
| object file |  | object file |  | object file |  | object file|
---------------  ---------------  ---------------  --------------
      |                 |               |               |
      |                 |               |               |
      |                 |               |               |
      |                 |               |               |
      |                 v    +----------+               |
      |                . . . v                          |
      |              .       .<-------------------------+
      +------------->. link  .  <------------     +--------+
                       . . .                |     | Runtime|
                         |                  +-----| Library|
                         v                        +--------+
                  ---------------
                  | Executable  |
                  |    Code     |
                  --------------- 
© www.minhinc.com
p10
 
Preprocessor - It is a program that runs as part of compilation of a c program.  It is not part of compiler. In simplistic terms, a C Preprocessor is just a text substitution tool and they instruct compiler to do required preprocessing before actual compilation.
All preprocessor commands begin with a pound symbol (#). It must be the first non blank character, and for readability, a preprocessor directive should begin in first column. Following section lists down all important preprocessor directives:
  
Directive              Description
#define                Substitutes a preprocessor macro
#include               Inserts a particular header from another file
#undef                 Undefines a preprocessor macro
#ifdef                 Returns true if this macro is defined
#ifndef                Returns true if this macro is not defined
#if                    Tests if a compile time condition is true
#else                  The alternative for #if
#elif                   #else an #if in one statement
#endif                 Ends preprocessor conditional
#error                 Prints error message on stderr
#pragma                Issues special commands to the compiler, using 
 
 
Tool - cpp
 
$ cat test.h 
#ifndef TEST_H
#define TEST_H
int func():
#endif
$ cat test.cpp
#include "test.h"
int main(){
return 0;
} 
 
$ cpp test.cpp 
# 1 "test.cpp"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.cpp"
# 1 "test.h" 1
 
int func():
# 2 "test.cpp" 2
int main(){
return 0;
} 
 
Compiling Source Files
Once your program is written in C, it is ready to be translated into a  machine-readable language.
A compiler translates C statements into machine statements
- A compiler creates object code, which is an intermediary step between source code and final executable code
- The compiler checks for syntax errors; e.g., Missing punctuation
- The compiler performs simple optimization on your code; e.g., eliminate a redundant statement
 
Tool - gcc
 
Linking Object Files
- The linker links together all object modules to form an executable image of the program
- The output of the linker is an executable image, which can be loaded into memory and executed
- The linker resolves any references to library functions
 - If your program uses a library routine, like sqrt, the linker finds the object code corresponding to this routine and links it within the final executable image
- The linker is automatically invoked by the compiler
 
Loading Your Program
The loader loads your program into the computer's memory
On most systems, this is performed automatically by the operating system
when you run the program
Most embedded systems require you to explicitly run a loader program
to get the program into memory
  
© www.minhinc.com
p11
Tool - gcc
  
Day 1 Morning
  1. Introduction
 
Executable file format which once loaded by a suitable executable loader, can be directly Executed by the CPU rather than become interpreted by software.
In addition to the binary application code, the executable may contain headers and tales with relocation and fix up information as well as various kinds of meta data.
ELF(Executable and Linkable File Format) - unix/linux
COFF(Command Object File Format) - windows
PE - windows
MZ - DOS
Mach-O (mac OS and iOS)
 
ELF Header
  
#define EI_NIDENT 16
typedef struct {
e_ident[EI_NIDENT];
unsigned char e_type;
Elf32_Half e_machine;
Elf32_Half e_version;
Elf32_Word e_entry;
Elf32_Addr e_phoff;
Elf32_Off e_shoff;
Elf32_Off e_flags;
Elf32_Word e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
 
 1. e_ident
 In order to support all this the initial information in ELF file contains information
 on how to interpret the file independent of the processor on which the executable is running.
 Name     Value      Purpose
 EI_MAG     0          File identification
 EI_MAG1    1          File identification
 EI_MAG2    2          File identification
 EI_MAG3    3          File identification
 EI_CLASS   4          File class
 EI_DATA    5          Data encoding
 EI_VERSION 6          File version
 EI_PAD     7          Start of padding bytes
 EI_NIDENT  16         Size of e_ident[]
 
    EI_MAG The first four bytes above hold the magic number 0x7fELF
    EI_CLASS An ELF can have two classes, 32 bit or 64 bit. This makes the file format portable.
    EI_DATA This member gives the information on data encoding, big endian or little endian format.
    EI_VERSION This member provides information on object file version.
    EI_PAD This member marks the start of unused bytes in the e_indent array of information.
    EI_NIDENT This member provides the size of array e_indent. This helps in parsing the ELF file.
 
 2. e_type
 This member identifies the type of object file. For example, an object file can be of
  following types :
 Name    Value    Meaning
 ET_NONE  0       No file type
 ET_REL   1       Relocatable file
 ET_EXEC  2       Executable file
 ET_DYN   3       Shared object file
 ET_CORE  4       Core file
 NOTE: The above list is not exhaustive but still gives information on main object
  file types that ELF can refer to.
 
 3. e_machine
 This member gives information on architecture that an ELF file requires.
 Name            Value      Meaning
 ET_NONE           0          No machine
 EM_M32            1          AT&T WE 32100
 EM_SPARC          2          SPARC
 EM_386            3          Intel Architecture
 EM_68K            4          Motorola 68000
 EM_88K            5          Motorola 88000
 EM_860            7          Intel 80860
 EM_MIPS           8          MIPS RS3000 Big-Endian
 EM_MIPS_RS4_BE   10          MIPS RS4000 Big-Endian
 RESERVED       11-16         Reserved for future use
 
 4. Additional Members
 Apart from the above three members, it also has the following members:
 e_version: Provides the ELF object file version information.
 e_entry: Provides the virtual address information of the entry point to which
  the system must transfer the control so that the process can be initiated.
 e_phoff: Holds the offset to program header table. This information is stored in
  terms of bytes. In absence of a program header table, the information
  contained by this member is zero.
 e_shoff: Holds the offset to section header table. As with e_phoff, this
  information too is stored in form of bytes and in absence of a section
  header table, the information contained by this field is zero.
 e_flags: Holds information related to process specific flags.
 e_ehsize: Holds information related to ELF header size in byes.
 e_phentsize: Holds information related to size of one entry in the object
  file's program header table. Note that all the entries are same in size.
 e_phnum: Holds the information related to number of entries in program header table.
 e_shentsize: Holds the information related to size of one entry in the
  section header table. The size is represented in form of number of bytes.
 e_shnum: Gives the information related to the number of entries in the section header table. 
 
Tool - readelf used to list the object data 
main() {
  printf("Hello World
");
} 
© www.minhinc.com
p12
 
$ readelf -h hello.o
  
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          312 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         13
  Section header string table index: 10 
 
 
$ readelf -S hello.o
  
There are 13 section headers, starting at offset 0x138:
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000015  0000000000000000  AX       0     0     4
  [ 2] .rela.text        RELA             0000000000000000  00000598
       0000000000000030  0000000000000018          11     1     8
  [ 3] .data             PROGBITS         0000000000000000  00000058
       0000000000000000  0000000000000000  WA       0     0     4
  [ 4] .bss              NOBITS           0000000000000000  00000058
       0000000000000000  0000000000000000  WA       0     0     4
  [ 5] .rodata           PROGBITS         0000000000000000  00000058
       000000000000000c  0000000000000000   A       0     0     1
  [ 6] .comment          PROGBITS         0000000000000000  00000064
       000000000000002e  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  00000092
       0000000000000000  0000000000000000           0     0     1
  [ 8] .eh_frame         PROGBITS         0000000000000000  00000098
       0000000000000038  0000000000000000   A       0     0     8
  [ 9] .rela.eh_frame    RELA             0000000000000000  000005c8
       0000000000000018  0000000000000018          11     8     8
  [10] .shstrtab         STRTAB           0000000000000000  000000d0
       0000000000000061  0000000000000000           0     0     1
  [11] .symtab           SYMTAB           0000000000000000  00000478
       0000000000000108  0000000000000018          12     9     8
  [12] .strtab           STRTAB           0000000000000000  00000580
       0000000000000013  0000000000000000           0     0     1 
The readelf program is capable of performing disassembly:
 
$ readelf -i 1 hello.o
  
0x00000000  pushl       %ebp
0x00000001  movl        %esp,%ebp
0x00000003  pushl       $0x0
0x00000008  call        0x08007559
0x0000000d  addl        $4,%esp
0x00000010  movl        %ebp,%esp
0x00000012  popl        %ebp
0x00000013  ret 
 
The .rel.text section contains the re-locations for the .text section of
the file, and we can display them as follows:
 
$ readelf -r hello.o
  
Relocation section data:.rel.text (0x2 entries)
Tag: 00004 Value 00301 R_386_32    (0 )
Tag: 00009 Value 00b02 R_386_PC32  (0 printf) 
 
$ readelf -l hello
  
Elf file type is EXEC (Executable file)
Entry point 0x400440
There are 9 program headers, starting at offset 64
 
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000000714 0x0000000000000714  R E    200000
  LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
                 0x0000000000000224 0x0000000000000228  RW     200000
  DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e28
                 0x00000000000001d0 0x00000000000001d0  RW     8
  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
                 0x0000000000000044 0x0000000000000044  R      4
  GNU_EH_FRAME   0x00000000000005ec 0x00000000004005ec 0x00000000004005ec
                 0x0000000000000034 0x0000000000000034  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
                 0x00000000000001f0 0x00000000000001f0  R      1
 
Section to Segment mapping:
Segment Sections...
   00
   01     .interp
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
   03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
   04     .dynamic
   05     .note.ABI-tag .note.gnu.build-id
   06     .eh_frame_hdr
   07
   08     .init_array .fini_array .jcr .dynamic .got 
  
© www.minhinc.com
p13
Day 1 Morning
  1. Introduction
 
Unix/Linux process virtual address space
  
high address -----------------------------
             |                           |    command line arguments
             |                           |  /  and environment
             -----------------------------
             |           stack           |
             - - - - - - - - - - - - - - -
             |             |             |
             |             |             |
             |             v             |
             |                           |
             |                           |
             |                           |
             |             ^             |
             |             |             |
             |             |             |
             - - - - - - - - - - - - - - -
             |           heap            |
             -----------------------------
             | uninitialized data        |  initialized to
             |          (bss)            | / zero by exec
             ----------------------------+
             | initialized data          |   read from
             -----------------------------   | program line
             |            text           |  / by exec
low address  |                           | /
             +---------------------------+ 
 
When an executable program is read into system memory by the kernel and executed, it becomes a process. We can consider system memory to be divided into two distinct regions.
 
One is user space, and the other is kernel Space. Every process has is own user space (about 2GB virtual space,32bit) and are prevented from interfering with one another. The mode change which is from user mode to kernel mode is called a context switch.
  
         -----------------
         |  Kernel Space |<----+
         |               |     |
         +---------------+     | context switching
         |               |     |
         | User Space    |<----+
         +---------------+ 
 
Text, Data and Stack.
The user process is divided into three segments or regions, they are: text, data and stack.
 
Text Segment.
The Text segment (a.k.a the Instruction segment) contains the executable program code and constant data. The text segment is marked by the operating system as read- only and can not be modified by the process.  Multiple processes can share the same text segment. Processes share the text segment if a second copy of the program is to be executed concurrently. Sharing can be turned off by using the -N option on the compile time.
 
Data Segment.
The data segment, which is contiguous (in a virtual sense) with the text segment, can be subdivided into initialized data (e.g. in C/C++, variables that are declared as static or are static by virtual of their placement) and uninitialized (or 0-initialized data. The uninitialized data area is also called BSS (Block Started By Symbol).
 
Heap Segment 
© www.minhinc.com
p14
During its execution lifetime, a process may request additional data segment space. Library memory allocation routines (e.g., new, malloc, calloc, etc.) in turn make use of the system calls brk and sbrk to extend the size of the data segment. The newly allocated space is added to the end of the current uninitialized data area. This area of available memory is also called "heap".
 
Stack Segment.
The stack segment is used by the process for the storage of automatic identifier, register variables, and function call information. The stack grows towards the uninitialized data segment.
 
The u area.
In addition to the text, data, and stack segment, the OS also maintains for each process a region called the u area (User Area). The u area contains information specific to the process (e.g. open files, current directory, signal action, accounting information) and a system stack segment for process use.  If the process makes a system call (e.g., the system call to write in the function in main ), the stack frame information for the system is stored in the system stack segment. Again, this information is kept by the OS in an area that the process doesn't normally have access to. Thus, if this information is needed, the process must use special system call to access it.  Like the process itself, the contents of the u area for the process are paged in and out bye the OS.
 
Process Memory Addresses.
The system keeps track of the virtual addresses associated with each user process segment. This addresses information is available to the process and can be obtained by referencing the external variables etext, edata, and end. The addresses (not the contents) of these three variable correspond respectively to the first valid address above the text, initialized data, and uninitialized data segments.
  
#include <iostream>
extern int etext, edata, end;
using namespace std;
int main( ){
cout << "Adr etext: " << hex << &etext << "	 ";
cout << "Adr edata: " << hex << &edata << "	 ";
cout << "Adr end: " << hex << &end << "
";
 
char *s1 = "hello"; //in initialized data segmenta
static int a=1; //in initialized data segment
static int b; //in uninitialized data segment
char s2[] = "hello"; //in the stack area.
int * c = new int;
 
cout <<hex << s1 << endl;
cout <<hex << &a << endl;
cout <<hex << &b << endl;
cout <<hex << s2 << endl;
cout <<hex << c << endl;
delete c;
return 0;
} 
 
$g++ add.cpp
$./a.out 
Adr etext: 0x400e4d     Adr edata: 0x602090     Adr end: 0x6021c0
hello
0x60208c
0x6021b8
hello
0X23ce010 
 
  
Day 1 Morning
  1. Introduction
 
A static library is set of object files that were copied into a single file. The static file is created with the archiver (ar). 
© www.minhinc.com
p15
 
<<calc_mean.c>> 
//#include <stdio.h>
double mean(double a, double b) {
return (a+b) / 2;
} 
 
<<calc_mean.h>> 
double mean(double, double); 
 
Creating the static library
First, calc_mean.c is turned into an object file:
  
$gcc -c calc_mean.c -o calc_mean.o 
 
Then, the archiver (ar) is invoked to produce a static library (named libmean.a) out of the object file calc_mean.o.
  
$ar  rcs libmean.a      calc_mean.o 
 
Note: the library must start with the three letters lib and have the suffix .a.
 
$cat calc.c 
#include <stdio.h>
#include "calc_mean.h"
int main(){
printf ("mean of 3, 6 is %f
",mean(3,6));
return 0;
} 
 
$ gcc -c calc_mean.c -o calc_mean.o
$ ar cr libmean.a calc_mean.o
$ gcc -c calc.c -o calc.o
$ gcc -o calc calc.o -L. -lmean
$ ./calc 
 
mean of 3, 6 is 4.500000 
 
$ gcc -o calc  -L. -lmean calc.o 
calc.o: In function 'main':
calc.c:(.text+0x2f): undefined reference to 'mean'
collect2: error: ld returned 1 exit status 
 
$ nm libmean.a 
calc_mean.o:
0000000000000000 T mean 
  
Day 1 Morning
  1. Introduction
 
Shared library (also known as a shared object, or as a dynamically linked library) is similar to a archive in that it is a grouping of object files.  When a shared library is linked into a program, the final executable does not actually contain the code that is present in the shared library. Instead, the executable merely contains a reference to the shared library.
 
The program using the library
<<main.c>> 
#include <stdio.h>
#include "calc_mean.h"
int main(){
printf ("mean of 3, 6 is %f
",mean(3,6));
return 0;
} 
 
$ gcc -c -fPIC calc_mean.c -o calc_mean.o
$ gcc -c calc.c -o calc.o 
© www.minhinc.com
p16
$ gcc -shared -fPIC -o libmean.so calc_mean.o
$ ldd libmean.so
  
linux-vdso.so.1 =>  (0x00007fffadffe000)
libc.so.6 => /lib64/libc.so.6 (0x00007f546f7ed000)
/lib64/ld-linux-x86-64.so.2 (0x00007f546fdc4000) 
 
$ gcc -o calc calc.o -L. -lmean
$ ldd calc
  
linux-vdso.so.1 =>  (0x00007fffa58de000)
libmean.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f4e10d70000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4e11146000) 
 
$ export LD_LIBRARY_PATH=.
$ ./calc
 
mean of 3, 6 is 4.500000
In order to avoid LD_LIBRARY_PATH programmer can add
-Wl,rpath,<lib path> to the command link line
 
$ pwd
/home/sc
 
$ echo $LD_LIBRARY_PATH
 
$ rm calc
$ gcc -o calc calc.o -L. -lmean -Wl,-rpath=/home/sc/
$ ./calc
mean of 3, 6 is 4.500000
 
$ gcc -o calc calc.o -L. -lmean
 
$ ./calc
./calc: error while loading shared libraries: libmean.so: cannot open shared object file: No such file or directory
  
Day 1 Morning
  1. Introduction
 
A calling convention describes how the arguments are passed and values returned by functions.
 
It also specifies how the function names are decorated.
 
 
1) C calling convention (__cdecl) 
int __cdecl sumExample (int a, int b); 
 
- Arguments are passed from right to left, and placed on the stack.
- Stack cleanup is performed by the caller.
- Function name is decorated by prefixing it with an underscore character '_' .
- The default calling convention for C and C++ programs. The advantage of this calling convention is that it allows functions with a variable number of arguments to be used. The disadvantage is that it creates larger executable.
 
2) Standard calling convention (__stdcall) 
int __stdcall sumExample (int a, int b); 
 
- Arguments are passed from right to left, and placed on the stack.
- Stack cleanup is performed by the called function.
- Function name is decorated by prepending an underscore character and appending a '@' character and the number of bytes of stack space required. 
© www.minhinc.com
p17
- It is used to call Win32 API functions. It does not allow functions to have a variable number of arguments.
 
3) Fast calling convention (__fastcall) 
int __fastcall sumExample (int a, int b); 
 
- The first two function arguments that require 32 bits or less are placed into registers ECX and EDX. The rest of them are pushed on the stack from right to left.
- Arguments are popped from the stack by the called function.
- Function name is decorated by by prepending a '@' character and appending a '@' and the number of bytes (decimal) of space required by the arguments.
- __fastcall attempts to put arguments in registers, rather than on the stack, thus making function calls faster.
 
 
4) Thiscall
- Arguments are passed from right to left, and placed on the stack. this is placed in ECX. Stack cleanup is performed by the called function.
- Thiscall calling convention is the default calling convention used by C++ member functions that do not use variable arguments.
  
Day 1 Morning
  1. Introduction
 
Name mangling is changing function names to avoid name conflict. Used in function overloading.
  
void fun(int x) {
    cout<<x<<endl;
}
void fun(float x) {
    cout<<x<<endl;
}
int main() {
    fun(10);
    fun(10.5f);
 
    return 0;
} 
 
Mangled name for funtion void fun(int x) is 
?fun@@YAXH@Z
Mangled name for funtion void fun(float x) is
?fun@@YAXM@Z
Tool - nm
#ifndef SAMPLE_H
#define SAMPLE_H
#include <iostream>
using namespace std;
struct fraction {
int numerator;
int denominator;
};
class cfraction{
int numerator;
int denominator;
public:
cfraction(int,int);
void func();
};
#endif
 
#include "sample.h"
cfraction::cfraction(int n,int d){
numerator=n;
denominator=d;
}
void cfraction::func(){
cout<<numerator/denominator;
} 
© www.minhinc.com
p18
 
$ g++ -c sample.cpp -o sample.o
 
$ nm sample.o 
00000000 b .bss
00000000 d .ctors
00000000 d .data
00000000 r .eh_frame
00000000 r .rdata$zzz
00000000 t .text
0000004b t ___tcf_0
0000008a t __GLOBAL__sub_I__ZN9cfractionC2Eii
0000005d t __Z41__static_initialization_and_destruction_0ii
0000001e T __ZN9cfraction4funcEv
00000000 T __ZN9cfractionC1Eii
00000000 T __ZN9cfractionC2Eii
         U __ZNSolsEi
         U __ZNSt8ios_base4InitC1Ev
         U __ZNSt8ios_base4InitD1Ev
         U __ZSt4cout
00000000 b __ZStL8__ioinit
         U _atexit 
  
Day 1 Morning
  1. Introduction
© www.minhinc.com
p19