################################################################################################################
#
#		STATICNA KNJIZNICA
################################################################################################################
$ gcc -c libprva.c -o libprva.o
$ ar rcs libprva.a libprva.o

	r - Insert the files member into archive (with  replacement)
	c - Create the archive. The specified archive is always created if it did not exist, when you request an update
	s - Write an object-file index into the archive, or update an existing one
	
$ gcc implicitna.c -o staticna libprva.a

$ readelf -h libprva.a # izpise zaglavje formata ELF od knjižnice
"     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:          592 (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 -h ./staticna  # izpise zaglavje formata ELF od izvedljivega modula
"      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:                              EXEC (Executable file)
	  Machine:                           Advanced Micro Devices X86-64
  	  Version:                           0x1
	  Entry point address:               0x400460
	  Start of program headers:          64 (bytes into file)
	  Start of section headers:          6320 (bytes into file)
	  Flags:                             0x0
	  Size of this header:               64 (bytes)
	  Size of program headers:           56 (bytes)
	  Number of program headers:         9
	  Size of section headers:           64 (bytes)
	  Number of section headers:         37
	  Section header string table index: 34
"  	
$ readelf -S -W libprva.a   # izpise vse sekcije
"	There are 13 section headers, starting at offset 0x250:

	Section Headers:
	  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
	  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
	  [ 1] .text             PROGBITS        0000000000000000 000040 00008c 00  AX  0   0  4
	  [ 2] .rela.text        RELA            0000000000000000 000760 000120 18     11   1  8
	  [ 3] .data             PROGBITS        0000000000000000 0000cc 000004 00  WA  0   0  4
	  [ 4] .bss              NOBITS          0000000000000000 0000d0 000000 00  WA  0   0  4
	  [ 5] .rodata           PROGBITS        0000000000000000 0000d0 000079 00   A  0   0  8
	  [ 6] .eh_frame         PROGBITS        0000000000000000 000150 000078 00   A  0   0  8
	  [ 7] .rela.eh_frame    RELA            0000000000000000 000880 000048 18     11   6  8
	  [ 8] .comment          PROGBITS        0000000000000000 0001c8 000024 00      0   0  1
	  [ 9] .note.GNU-stack   PROGBITS        0000000000000000 0001ec 000000 00      0   0  1
	  [10] .shstrtab         STRTAB          0000000000000000 0001ec 000061 00      0   0  1
	  [11] .symtab           SYMTAB          0000000000000000 000590 000180 18     12   9  8
	  [12] .strtab           STRTAB          0000000000000000 000710 00004d 00      0   0  1
	Key to Flags:
	  W (write), A (alloc), X (execute), M (merge), S (strings)
	  I (info), L (link order), G (group), x (unknown)
	  O (extra OS processing required) o (OS specific), p (processor specific)
"	  
$ readelf -s libprva.a  # izpise simbolno tabelo knjiznice
"	File: libprva.a(libprva.o)
	Symbol table '.symtab' contains 16 entries:
	   Num:    Value          Size Type    Bind   Vis      Ndx Name
	     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS libprva.c
	     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
	     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     	     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
	     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
	     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     	     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 
     	     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
	     9: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 vrednost
	    10: 0000000000000000    59 FUNC    GLOBAL DEFAULT    1 izpisi_pozdrav
	    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND puts
	    12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
	    13: 0000000000000008     8 OBJECT  GLOBAL DEFAULT  COM kazalec
	    14: 000000000000003b    48 FUNC    GLOBAL DEFAULT    1 vrni_vsoto
	    15: 000000000000006b    33 FUNC    GLOBAL DEFAULT    1 izpisi_niz
"
$ readelf -r libprva.a # izpise relokacijske tabele knjiznice
"
	Relocation section '.rela.text' at offset 0x760 contains 12 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000000005  00050000000a R_X86_64_32       0000000000000000 .rodata + 0
	00000000000a  000b00000002 R_X86_64_PC32     0000000000000000 puts + fffffffffffffffc
	000000000010  000900000002 R_X86_64_PC32     0000000000000000 vrednost + fffffffffffffffc
	000000000015  00050000000a R_X86_64_32       0000000000000000 .rodata + 20
	00000000001f  000c00000002 R_X86_64_PC32     0000000000000000 printf + fffffffffffffffc
	000000000026  000d00000002 R_X86_64_PC32     0000000000000008 kazalec + fffffffffffffffc
	00000000002b  00050000000a R_X86_64_32       0000000000000000 .rodata + 40
	000000000035  000c00000002 R_X86_64_PC32     0000000000000000 printf + fffffffffffffffc
	000000000053  00050000000a R_X86_64_32       0000000000000000 .rodata + 5c
	00000000005d  000c00000002 R_X86_64_PC32     0000000000000000 printf + fffffffffffffffc
	00000000007c  00050000000a R_X86_64_32       0000000000000000 .rodata + 69
	000000000086  000c00000002 R_X86_64_PC32     0000000000000000 printf + fffffffffffffffc
	
	Relocation section '.rela.eh_frame' at offset 0x880 contains 3 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000000020  00020000000a R_X86_64_32       0000000000000000 .text + 0
	000000000040  00020000000a R_X86_64_32       0000000000000000 .text + 3b
	000000000060  00020000000a R_X86_64_32       0000000000000000 .text + 6b
"
	Offset . odmik od zacetka sekcije do mesta prenaslavljanja
	Info - vstop v simbolno tabelo in tip prenaslavljanja
	Sym.Value - vrednost simbola v simbolni tabeli
	Sym.Name -ime simbola v simboni tabeli

$ readelf -s ./staticna  # izpise simbolno tabelo izvedljivega modula
"
	Symbol table '.dynsym' contains... 
"
$ readelf -r ./staticna # izpise relokacijske tabele izvedljivega modula
"
	Relocation section '.rela.dyn' at offset 0x3a8 contains 1 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000600fe0  000200000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
	
	Relocation section '.rela.plt' at offset 0x3c0 contains 3 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000601000  000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf + 0
	000000601008  000300000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0
	000000601010  000400000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
"
	Offset . odmik od zacetka sekcije do mesta prenaslavljanja
	Info - vstop v simbolno tabelo in tip prenaslavljanja
	Sym.Value - vrednost simbola v simbolni tabeli
	Sym.Name -ime simbola v simboni tabeli

$ strip --strip-unneeded staticna # odstranimo vse nepotrebne simbole
$ readelf -s ./staticna	# izpisemo simbolno tabelo
"
	Symbol table '.dynsym' contains 5 entries:
	   Num:    Value          Size Type    Bind   Vis      Ndx Name
	     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
	     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
	     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
	     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
"
################################################################################################################
#
#		DINAMICNA KNJIZNICA
################################################################################################################

#Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system).
$ gcc -c -fPIC libprva.c

$ readelf -r libprva.o # izpise relokacijske tabele izvedljivega modula
"
	Relocation section '.rela.text' at offset 0x7a0 contains 12 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000000007  000500000002 R_X86_64_PC32     0000000000000000 .rodata + fffffffffffffffc
	00000000000c  000c00000004 R_X86_64_PLT32    0000000000000000 puts + fffffffffffffffc
	000000000013  000900000009 R_X86_64_GOTPCREL 0000000000000000 vrednost + fffffffffffffffc
	00000000001c  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 1c
	000000000026  000d00000004 R_X86_64_PLT32    0000000000000000 printf + fffffffffffffffc
	00000000002d  000e00000009 R_X86_64_GOTPCREL 0000000000000008 kazalec + fffffffffffffffc
	000000000037  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 3c
	000000000041  000d00000004 R_X86_64_PLT32    0000000000000000 printf + fffffffffffffffc
	000000000061  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 58
	00000000006b  000d00000004 R_X86_64_PLT32    0000000000000000 printf + fffffffffffffffc
	00000000008c  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 65
	000000000096  000d00000004 R_X86_64_PLT32    0000000000000000 printf + fffffffffffffffc

	Relocation section '.rela.eh_frame' at offset 0x8c0 contains 3 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0
	000000000040  000200000002 R_X86_64_PC32     0000000000000000 .text + 47
	000000000060  000200000002 R_X86_64_PC32     0000000000000000 .text + 79
"
#Primerjaj z $ readelf -r libprva.a

$ ld -shared -soname libprva.so.1 -o libprva.so.1.0 libprva.o
# Z zastavico -shared povemo, da se mora modul pred izvajanjem povezal še z drugimi moduli (torej nima vstopne točke), z zastavico -soname  ime_datoteke.so.verzija_vmesnika pa povemo, katera verzija vmesnika je implementirana. Vedno ko spremenimo vmesnik knjižnice, moramo spremeniti tudi to verzijo, saj se na ta način izognemo težavam z nekompatibilnimi knjižnicami. Vidimo, da ima tudi izhodni modul na koncu dve številki. Prva pove številko vmesnika, druga pa njegovo verzijo.		
	
$ ldconfig -v -n .
"	.:
		libprva.so.1 -> libprva.so.1.0 (changed)
"
#Dobili smo knjižnico, ki jo moramo sedaj še namestiti. V kolikor jo želimo dani na voljo vsem, jo kopiramo v mapo /usr/lib ali /lib, v našem primeru pa jo bomo pustili kar v trenutni mapi. V vsakem primeru pa moramo pognati ukaz ldconfig, ki poišče zadnjo verzijo vsake knjižnice. V našem primeru smo napisali ukaz, ki bo iskal nove verzije samo v trenutni mapi. 

# zastavice
#       -v --verbose
#              Verbose mode.  Print current version number, the name of each directory as it is scanned and any links that are
#              created.
#       -n     Only process directories specified on the command line.  Don’t process the trusted  directories  (/usr/lib  and
#              /lib) nor those specified in /etc/ld.so.conf.  Implies -N.

	
$ ls -all
# Sedaj je ustvarjena nova povezava z imenom libprva.so.1, ki kaže na libprva.so.1.0. Ukaz "ldconfig -v -n ." torej poskrbi, da nam ni potrebno skrbeti za podverzijo knjižnice.
	
$ ln -sf libprva.so.1 libprva.so
# Na koncu lahko naredimo še simbolično povezavo do te knjižnice (man ln)

$ ls -all
# bodite pozorni na simbolično povezavo libprva.so -> libprva.so.1

$  readelf -h libprva.so 
"     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:                              DYN (Shared object file)
	  Machine:                           Advanced Micro Devices X86-64
	  Version:                           0x1
	  Entry point address:               0x380
	  Start of program headers:          64 (bytes into file)
	  Start of section headers:          1840 (bytes into file)
	  Flags:                             0x0
	  Size of this header:               64 (bytes)
	  Size of program headers:           56 (bytes)
	  Number of program headers:         4
	  Size of section headers:           64 (bytes)
	  Number of section headers:         19
	  Section header string table index: 16
"
$ readelf -s libprva.so
"Symbol table '.dynsym' contains 12 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000380     0 SECTION LOCAL  DEFAULT    7 
     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
     3: 0000000000000380    71 FUNC    GLOBAL DEFAULT    7 izpisi_pozdrav
     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND puts
     5: 0000000000200688     8 OBJECT  GLOBAL DEFAULT   14 kazalec
     6: 00000000000003f9    35 FUNC    GLOBAL DEFAULT    7 izpisi_niz
     7: 00000000000003c7    50 FUNC    GLOBAL DEFAULT    7 vrni_vsoto
     8: 0000000000200684     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     9: 0000000000200684     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    10: 0000000000200690     0 NOTYPE  GLOBAL DEFAULT  ABS _end
    11: 0000000000200680     4 OBJECT  GLOBAL DEFAULT   13 vrednost

Symbol table '.symtab' contains 29 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	...
    16: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS libprva.c
    17: 0000000000200518     0 OBJECT  LOCAL  HIDDEN  ABS _DYNAMIC
    18: 0000000000200658     0 OBJECT  LOCAL  HIDDEN  ABS _GLOBAL_OFFSET_TABLE_
    19: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    20: 0000000000000380    71 FUNC    GLOBAL DEFAULT    7 izpisi_pozdrav
    21: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND puts
    22: 0000000000200688     8 OBJECT  GLOBAL DEFAULT   14 kazalec
    23: 00000000000003f9    35 FUNC    GLOBAL DEFAULT    7 izpisi_niz
    24: 00000000000003c7    50 FUNC    GLOBAL DEFAULT    7 vrni_vsoto
    25: 0000000000200684     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    26: 0000000000200684     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    27: 0000000000200690     0 NOTYPE  GLOBAL DEFAULT  ABS _end
    28: 0000000000200680     4 OBJECT  GLOBAL DEFAULT   13 vrednost
"
# Simbolna tabela .symtab podvaja vrednosti dinamične simbolne tabele .dynsym
#Primerjaj z $ readelf -s libprva.a

$ readelf -r libprva.so
"
	Relocation section '.rela.dyn' at offset 0x2f0 contains 2 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000200648  000500000006 R_X86_64_GLOB_DAT 0000000000200688 kazalec + 0
	000000200650  000b00000006 R_X86_64_GLOB_DAT 0000000000200680 vrednost + 0
	
	Relocation section '.rela.plt' at offset 0x320 contains 2 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000200670  000200000007 R_X86_64_JUMP_SLO 0000000000000000 printf + 0
	000000200678  000400000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0
"
$ readelf -SW libprva.so # izpisemo vse sekcije
"	There are 19 section headers, starting at offset 0x730:

	Section Headers:
	  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
	  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
	  [ 1] .hash             HASH            0000000000000120 000120 000044 04   A  2   0  8
	  [ 2] .dynsym           DYNSYM          0000000000000168 000168 000120 18   A  3   2  8
	  [ 3] .dynstr           STRTAB          0000000000000288 000288 000068 00   A  0   0  1
	  [ 4] .rela.dyn         RELA            00000000000002f0 0002f0 000030 18   A  2   0  8
	  [ 5] .rela.plt         RELA            0000000000000320 000320 000030 18   A  2   6  8
	  [ 6] .plt              PROGBITS        0000000000000350 000350 000030 10  AX  0   0  4
	  [ 7] .text             PROGBITS        0000000000000380 000380 00009c 00  AX  0   0  4
	  [ 8] .rodata           PROGBITS        0000000000000420 000420 000079 00   A  0   0  8
	  [ 9] .eh_frame         PROGBITS        00000000000004a0 0004a0 000078 00   A  0   0  8
	  [10] .dynamic          DYNAMIC         0000000000200518 000518 000130 10  WA  3   0  8
	  [11] .got              PROGBITS        0000000000200648 000648 000010 08  WA  0   0  8
	  [12] .got.plt          PROGBITS        0000000000200658 000658 000028 08  WA  0   0  8
	  [13] .data             PROGBITS        0000000000200680 000680 000004 00  WA  0   0  4
	  [14] .bss              NOBITS          0000000000200688 000684 000008 00  WA  0   0  8
	  [15] .comment          PROGBITS        0000000000000000 000684 000024 00      0   0  1
	  [16] .shstrtab         STRTAB          0000000000000000 0006a8 000088 00      0   0  1
	  [17] .symtab           SYMTAB          0000000000000000 000bf0 0002b8 18     18  19  8
	  [18] .strtab           STRTAB          0000000000000000 000ea8 000084 00      0   0  1
	Key to Flags:
	  W (write), A (alloc), X (execute), M (merge), S (strings)
	  I (info), L (link order), G (group), x (unknown)
	  O (extra OS processing required) o (OS specific), p (processor specific)
"
$ objdump -d -j .plt libprva.so  # izpišemo vsebino sekcije plt (Procedure Linkage Table)
"
	libprva.so:     file format elf64-x86-64
	
	Disassembly of section .plt:
	
	0000000000000350 <printf@plt-0x10>:
	 350:	ff 35 0a 03 20 00    	pushq  0x20030a(%rip)        # 200660 <_GLOBAL_OFFSET_TABLE_+0x8>
	 356:	ff 25 0c 03 20 00    	jmpq   *0x20030c(%rip)        # 200668 <_GLOBAL_OFFSET_TABLE_+0x10>
	 35c:	0f 1f 40 00          	nopl   0x0(%rax)
	
	0000000000000360 <printf@plt>:
	 360:	ff 25 0a 03 20 00    	jmpq   *0x20030a(%rip)        # 200670 <_GLOBAL_OFFSET_TABLE_+0x18>
	 366:	68 00 00 00 00       	pushq  $0x0
	 36b:	e9 e0 ff ff ff       	jmpq   350 <printf@plt-0x10>
	
	0000000000000370 <puts@plt>:
	 370:	ff 25 02 03 20 00    	jmpq   *0x200302(%rip)        # 200678 <_GLOBAL_OFFSET_TABLE_+0x20>
	 376:	68 01 00 00 00       	pushq  $0x1
	 37b:	e9 d0 ff ff ff       	jmpq   350 <printf@plt-0x10>
"
# za razlago delovanje tabele plt glej slikovni material na sistemu za vaje 

$ objdump -s libprva.so | grep -A 2 got
"
	Contents of section .got:
	 200648 00000000 00000000 00000000 00000000  ................
	Contents of section .got.plt:
	 200658 18052000 00000000 00000000 00000000  .. .............
	 200668 00000000 00000000 66030000 00000000  ........f.......
"
$ readelf -I libprva.so
"
	Histogram for bucket list length (total of 3 buckets):
	 Length  Number     % of total  Coverage
	      0  0          (  0.0%)
	      1  1          ( 33.3%)     10.0%
	      2  1          ( 33.3%)     30.0%
	      3  0          (  0.0%)     30.0%
	      4  0          (  0.0%)     30.0%
	      5  0          (  0.0%)     30.0%
	      6  0          (  0.0%)     30.0%
	      7  1          ( 33.3%)    100.0%
"
# 3 buckets - trije vstopi v hash tabelo
# length - dolžina verige (chain) v hash tabeli
# number - število vstopov v hash tabelo s specificirano dolžino verige

# še malo večji primer .so knjižnice
$ readelf -I /lib/libc.so.6 
"	Histogram for bucket list length (total of 1017 buckets):
 	Length  Number     % of total  Coverage
	      0  116        ( 11.4%)
	      1  268        ( 26.4%)     12.7%
	      2  283        ( 27.8%)     39.4%
	      3  194        ( 19.1%)     66.9%
	      4  100        (  9.8%)     85.8%
	      5  40         (  3.9%)     95.3%
	      6  12         (  1.2%)     98.7%
	      7  4          (  0.4%)    100.0%
"

$ sudo apt-get install elfutils  # eu-readelf pove še povprečno število iskanj v hash tabeli...
$ eu-readelf -I libprva.so
"
	Histogram for bucket list length in section [ 1] '.hash' (total of 3 buckets):
	 Addr: 0x0000000000000120  Offset: 0x000120  Link to section: [ 2] '.dynsym'
 	Length  Number  % of total  Coverage
	      0       0        0.0%
	      1       1       33.3%     10.0%
	      2       1       33.3%     30.0%
	      3       0        0.0%     30.0%
	      4       0        0.0%     30.0%
	      5       0        0.0%     30.0%
	      6       0        0.0%     30.0%
	      7       1       33.3%    100.0%
	 Average number of tests:   successful lookup: 3.200000
        	                  unsuccessful lookup: 3.333333
"
$ eu-readelf -I /lib/libc.so.6 
################################################################################################################
#
#		DINAMICNA KNJIZNICA IMPLICITNO POVEZOVANJE
################################################################################################################

$ gcc implicitna.c -o implicitna -L. -lprva
#Ker uporabljamo dinamične knjižnice moramo program prevesti z dodatnimi zastavicami. Uporabiti moramo zastavico -L, s katero povemo, kje naj povezovalnik išče knjižnice in zastavico -l s katero vključimo knjižnico v program.

$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
#Preden lahko program zaženemo mu moramo na nek način sporočiti, kje lahko najde dinamično knjižnico. Ponavadi se vse knjižnice nahajajo v mapi /usr/lib, /usr/local/lib oz mapah, navedenih v datoteki /etc/ld.so.conf. Knjižnice se iščejo tudi v poteh navedenih v spremenljivki LD_LIBRARY_PATH. V našem primeru bomo knjižnico imeli kar v trenutni mapi, ki jo bomo dodali v spremenljivko z ukazom:

$ ./implicitna	# Sedaj lahko zaženemo program.

$ readelf -h ./implicitna
"	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:                              EXEC (Executable file)
	  Machine:                           Advanced Micro Devices X86-64
	  Version:                           0x1
	  Entry point address:               0x400670
	  Start of program headers:          64 (bytes into file)
	  Start of section headers:          6304 (bytes into file)
	  Flags:                             0x0
	  Size of this header:               64 (bytes)
	  Size of program headers:           56 (bytes)
	  Number of program headers:         9
	  Size of section headers:           64 (bytes)
	  Number of section headers:         37
	  Section header string table index: 34
"
$ readelf -s ./implicitna
"
	Symbol table '.dynsym' contains 13 entries:
	   Num:    Value          Size Type    Bind   Vis      Ndx Name
	     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
	     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND vrni_vsoto
     	     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     	     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
	     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND izpisi_niz
	     6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
	     7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND izpisi_pozdrav
	     8: 0000000000601060     0 NOTYPE  GLOBAL DEFAULT  ABS _end
	     9: 0000000000601040     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
	    10: 0000000000601040     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
	    11: 0000000000601040     4 OBJECT  GLOBAL DEFAULT   25 vrednost
	    12: 0000000000601048     8 OBJECT  GLOBAL DEFAULT   25 kazalec
"
# primirjaj z $ readelf -s ./staticna

$ readelf -r ./implicitna
"
	Relocation section '.rela.dyn' at offset 0x510 contains 3 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000600fe0  000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
	000000601040  000b00000005 R_X86_64_COPY     0000000000601040 vrednost + 0
	000000601048  000c00000005 R_X86_64_COPY     0000000000601048 kazalec + 0
	
	Relocation section '.rela.plt' at offset 0x558 contains 6 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000601000  000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf + 0
	000000601008  000200000007 R_X86_64_JUMP_SLO 0000000000000000 vrni_vsoto + 0
	000000601010  000400000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0
	000000601018  000500000007 R_X86_64_JUMP_SLO 0000000000000000 izpisi_niz + 0
	000000601020  000600000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
	000000601028  000700000007 R_X86_64_JUMP_SLO 0000000000000000 izpisi_pozdrav + 0
"
# primerjaj z $ readelf -r ./staticna
$ strip --strip-unneeded implicitna
$ readelf -s ./implicitna
################################################################################################################
#
#		DINAMICNA KNJIZNICA EXPLICITNO POVEZOVANJE
################################################################################################################

$ gcc eksplicitno.c -o eksplicitna -ldl
# Da lahko prevedemo program, moramo zraven vključiti še knjižnico libdl. Pri gcc uporabimo torej še zastavico -ldl.

$ readelf -h ./eksplicitna
"
	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:                              EXEC (Executable file)
	  Machine:                           Advanced Micro Devices X86-64
	  Version:                           0x1
	  Entry point address:               0x400600
	  Start of program headers:          64 (bytes into file)
	  Start of section headers:          6320 (bytes into file)
	  Flags:                             0x0
	  Size of this header:               64 (bytes)
	  Size of program headers:           56 (bytes)
	  Number of program headers:         9
	  Size of section headers:           64 (bytes)
	  Number of section headers:         37
	  Section header string table index: 34
"
$ readelf -s ./eksplicitna
"
	...
"
$ readelf -r ./eksplicitna
"	Relocation section '.rela.dyn' at offset 0x4a0 contains 1 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000600fe0  000200000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
	
	Relocation section '.rela.plt' at offset 0x4b8 contains 7 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000601000  000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf + 0
	000000601008  000400000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0
	000000601010  000500000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
	000000601018  000600000007 R_X86_64_JUMP_SLO 0000000000000000 dlclose + 0
	000000601020  000700000007 R_X86_64_JUMP_SLO 0000000000000000 dlopen + 0
	000000601028  000800000007 R_X86_64_JUMP_SLO 0000000000000000 dlsym + 0
	000000601030  000900000007 R_X86_64_JUMP_SLO 0000000000000000 perror + 0
"
# primerjaj z $ readelf -r ./staticna
# primerjaj z $ readelf -r ./implicitna
$ strip --strip-unneeded eksplicitna
$ readelf -s ./eksplicitna