consolidate all repos to one for archive

This commit is contained in:
2025-01-28 13:46:42 +01:00
commit a6610fbc7a
5350 changed files with 2705721 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
all: lib build run clean
build:
gcc -m32 main.c -o demo_eksplicitno -ldl
run:
./demo_eksplicitno "Jaz Sem Velik" 2 5
clean:
rm -f demo_eksplicitno libXPO.a libXPO.o libXPO.so
lib:
gcc -m32 -c libXPO.c -o libXPO.o
gcc -m32 -shared -o libXPO.so libXPO.o
zip:
zip eksplicitno.zip Makefile libXPO.c libXPO.h main.c

View File

@@ -0,0 +1,17 @@
#include "libXPO.h"
#include <string.h>
#include <stdio.h>
uint32_t sestej(uint32_t a, uint32_t b)
{
return a+b;
}
void niz_veliki(char* niz)
{
size_t size = strlen(niz);
for (size_t i = 0; i < size; i++)
if(niz[i] >= 'a' && niz[i] <= 'z')
niz[i] -= 32;
}

View File

@@ -0,0 +1,5 @@
#include <inttypes.h>
#include <stdlib.h>
uint32_t sestej(uint32_t a, uint32_t b);
void niz_veliki(char* niz);

View File

@@ -0,0 +1,71 @@
#include <stdio.h>
#include <dlfcn.h>
#include <locale.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
if(argc < 3){
printf("Usage");
return 0;
}
char* niz = argv[1];
int i = atoi(argv[2]);
int j = atoi(argv[3]);
void* handle = NULL;
void (*izpis)();
int (*vsota)(int,int);
handle = dlopen("./libXPO.so",RTLD_LAZY);
if (handle == NULL)
{
perror("Ne morem odpreti libprva.so\n");
return -1;
}
izpis=(void(*)(void))dlsym(handle,"niz_veliki");
if (izpis==NULL)
{
perror("Ne najdem funkcije izpisi_pozdrav\n");
return -2;
}
izpis(niz);
printf("%s\n", niz);
vsota=(int(*)(int,int))dlsym(handle,"sestej");
if (vsota==NULL)
{
perror("Ne najdem funkcije sestej\n");
return -3;
}
printf("rezultat: %d\n",vsota(i,j));
dlclose(handle);
return 0;
}

View File

@@ -0,0 +1,17 @@
all: lib build run
build:
gcc -m32 main.c -o demo_implicitno -L. -lXPO
run:
./demo_implicitno "Jaz Sem Velik" 2 5
clean:
rm -f demo_implicitno libXPO.a libXPO.o libXPO.so
lib:
gcc -m32 -c libXPO.c -o libXPO.o
gcc -m32 -shared -o libXPO.so libXPO.o
zip:
zip implicitno.zip Makefile libXPO.c libXPO.h main.c

View File

@@ -0,0 +1,17 @@
#include "libXPO.h"
#include <string.h>
#include <stdio.h>
uint32_t sestej(uint32_t a, uint32_t b)
{
return a+b;
}
void niz_veliki(char* niz)
{
size_t size = strlen(niz);
for (size_t i = 0; i < size; i++)
if(niz[i] >= 'a' && niz[i] <= 'z')
niz[i] -= 32;
}

View File

@@ -0,0 +1,5 @@
#include <inttypes.h>
#include <stdlib.h>
uint32_t sestej(uint32_t a, uint32_t b);
void niz_veliki(char* niz);

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include "libXPO.h"
//export LD_LIBRARY_PATH=.
int main(int argc, char** argv)
{
char* niz = argv[1];
int i = atoi(argv[2]);
int j = atoi(argv[3]);
niz_veliki(niz);
printf("%s\n", niz);
printf("rezultat: %d\n", sestej(i,j));
return 0;
}

View File

@@ -0,0 +1,17 @@
all: lib build run
build:
gcc -m32 main.c -o demo_staticno libXPO.a
run:
./demo_staticno "Jaz Sem Velik" 5 6
clean:
rm -f demo_staticno libXPO.a libXPO.o
lib:
gcc -m32 -c libXPO.c -o libXPO.o
ar rcs libXPO.a libXPO.o
zip:
zip staticno.zip Makefile libXPO.c libXPO.h main.c

View File

@@ -0,0 +1,17 @@
#include "libXPO.h"
#include <string.h>
#include <stdio.h>
uint32_t sestej(uint32_t a, uint32_t b)
{
return a+b;
}
void niz_veliki(char* niz)
{
size_t size = strlen(niz);
for (size_t i = 0; i < size; i++)
if(niz[i] >= 'a' && niz[i] <= 'z')
niz[i] -= 32;
}

View File

@@ -0,0 +1,5 @@
#include <inttypes.h>
#include <stdlib.h>
uint32_t sestej(uint32_t a, uint32_t b);
void niz_veliki(char* niz);

View File

@@ -0,0 +1,14 @@
#include <stdio.h>
#include "libXPO.h"
int main(int argc, char** argv)
{
char* niz = argv[1];
int i = atoi(argv[2]);
int j = atoi(argv[3]);
niz_veliki(niz);
printf("%s\n", niz);
printf("rezultat: %d\n", sestej(i,j));
return 0;
}

View File

@@ -0,0 +1,51 @@
################################################################################################################
#
# 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
################################################################################################################
#
# DINAMICNA KNJIZNICA
################################################################################################################
$ gcc -c -fPIC libprva.c
$ ld -shared -soname libprva.so.1 -o libprva.so.1.0 libprva.o
$ ldconfig -v -n .
$ ln -sf libprva.so.1 libprva.so
################################################################################################################
#
# 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.
$ strip --strip-unneeded 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.
$ strip --strip-unneeded eksplicitna

View File

@@ -0,0 +1,18 @@
all: libprva.o
ld -shared -soname libprva.so.1 -o libprva.so.1.0 libprva.o
ldconfig -v -n .
ln -sf libprva.so.1 libprva.so
gcc implicitna.c -o implicitna -L. -lprva
gcc eksplicitno.c -o eksplicitna -ldl
libprva.o: libprva.c
gcc -c -fPIC libprva.c
clean:
rm -f libprva.o
rm -f libprva.so.1.0
rm -f libprva.so.1
rm -f libprva.so
rm -f implicitna
rm -f eksplicitna

View File

@@ -0,0 +1,5 @@
# Knjižnice
## Prevajanje in vključevanje zunanjih modulov
Za demonstracijo preverite zbirko ukazi.txt.

View File

@@ -0,0 +1,60 @@
#include <dlfcn.h>
#include <locale.h>
#include <stdio.h>
int main()
{
void* handle = NULL;
void (*izpis)();
int (*vsota)(int,int);
printf("Primer eksplicitne uporabe dinamicnih knjiznic\n");
handle = dlopen("./libprva.so",RTLD_LAZY);
if (handle == NULL)
{
perror("Ne morem odpreti libprva.so\n");
return -1;
}
/* Klic prve funkcije */
izpis=(void(*)(void))dlsym(handle,"izpisi_pozdrav");
if (izpis==NULL)
{
perror("Ne najdem funkcije izpisi_pozdrav\n");
return -2;
}
izpis();
/* Klic druge funkcije */
vsota=(int(*)(int,int))dlsym(handle,"vrni_vsoto");
if (vsota==NULL)
{
perror("Ne najdem funkcije vrni_vsota\n");
return -3;
}
printf("Vsota: %d\n",vsota(40,2));
/* Klic tretje funkcije */
void (*izpisi_niz)(char*);
izpisi_niz=(void(*)(char*))dlsym(handle,"izpisi_niz");
if (izpisi_niz==NULL)
{
perror("Ne najdem funkcije izpisi_niz\n");
return -7;
}
izpisi_niz("Niz, ki ga izpise 3. funkcija!");
/* Spremenljivka */
int *spremenljivka;
spremenljivka=(int *)dlsym(handle,"vrednost");
if (spremenljivka==NULL)
{
perror("Ne najdem spremenljivke vrednost\n");
return -7;
}
printf("Spremenljivka ima vrednost: %d\n",*spremenljivka);
dlclose(handle);
return 0;
}

View File

@@ -0,0 +1,20 @@
#include <stdio.h>
#include "libprva.h"
int main()
{
char *niz="Niz iz glavnega programa\0";
printf("-----Zacetek-----\n");
izpisi_pozdrav();
printf("-----------------\n");
vrednost=42;
kazalec=(int *)niz;
izpisi_pozdrav();
printf("-----------------\n");
int v=vrni_vsoto(2,3);
printf("Vrnjena vsota je %d\n", v);
printf("-----------------\n");
izpisi_niz(niz);
printf("-------Konec-----\n");
return 0;
}

View File

@@ -0,0 +1,29 @@
#include <stdio.h>
/* Primer spremenljivke*/
int vrednost=999;
/* Primer kazalca */
int* kazalec;
/* Primer funkcije brez parametrov */
void izpisi_pozdrav()
{
printf("Pozdrav iz dinamicne knjiznice.\n");
printf("Spremenljivka vrednost je: %d\n ",vrednost);
printf("Kazalec kaze na naslov: %p\n",kazalec);
}
/* Primer funkcije z enim vhodnim in dvema vhodnima parametroma*/
int vrni_vsoto(int a, int b)
{
printf("Vsota je %d\n",a+b);
return a+b;
}
/* Primer funkcije, ki ima kot vhod kazalec na niz (zero terminated)*/
void izpisi_niz(char* niz)
{
printf("Vhodni niz: %s\n",niz);
}

View File

@@ -0,0 +1,9 @@
/* Prototipi funkcij in spremenljivk */
extern int vrednost;
extern int* kazalec;
void izpisi_pozdrav();
int vrni_vsoto(int a, int b);
void izpisi_niz(char* niz);

View File

@@ -0,0 +1,529 @@
################################################################################################################
#
# 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. Dont 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