consolidate all repos to one for archive
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
all: build run
|
||||
|
||||
debug: buildd run clean
|
||||
|
||||
zip:
|
||||
zip naloga.zip main.c Makefile podatki.c podatki.h
|
||||
|
||||
build: main.c podatki.c podatki.h
|
||||
gcc -m32 -O3 main.c podatki.c -o demo_podatki
|
||||
|
||||
buildd: main.c podatki.c podatki.h
|
||||
gcc -g -m32 main.c podatki.c -o demo_podatki -fsanitize=address -fno-omit-frame-pointer
|
||||
|
||||
run:
|
||||
time ./demo_podatki
|
||||
|
||||
clean:
|
||||
rm -f demo_podatki
|
11
semester_4/namenska_programska_oprema/Naloga_1/Vaja_1/main.c
Normal file
11
semester_4/namenska_programska_oprema/Naloga_1/Vaja_1/main.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "podatki.h"
|
||||
|
||||
int main(){
|
||||
void* pomnilnik = rezerviraj(sizeof(uint16_t)*6);
|
||||
vstavi(pomnilnik);
|
||||
izpis(pomnilnik);
|
||||
brisi(pomnilnik);
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "podatki.h"
|
||||
|
||||
uint16_t* rezerviraj(int velikostZlogi){
|
||||
uint16_t* ret = malloc(velikostZlogi);
|
||||
for (size_t i = 0; i < velikostZlogi/sizeof(uint16_t); i++)
|
||||
{
|
||||
ret[i] = 26132;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void brisi(uint16_t* pomnilnik){
|
||||
free(pomnilnik);
|
||||
}
|
||||
|
||||
uint16_t* vstavi(uint16_t* pomnilnik){
|
||||
uint8_t* point = (uint8_t*)pomnilnik;
|
||||
*(char*)point = 'X';
|
||||
point++;
|
||||
*(char*)point = 'P';
|
||||
point++;
|
||||
*(char*)point = 'O';
|
||||
point++;
|
||||
*(float*)point = (22.0/7.0);
|
||||
point += 4;
|
||||
*(uint32_t*)point = 26132;
|
||||
point += 4;
|
||||
*(char*)point = '!';
|
||||
}
|
||||
|
||||
void izpis(uint16_t* pomnilnik){
|
||||
uint8_t* point = (uint8_t*)pomnilnik;
|
||||
printf("%c\n", *(char*)point);
|
||||
point++;
|
||||
printf("%c\n", *(char*)point);
|
||||
point++;
|
||||
printf("%c\n", *(char*)point);
|
||||
point++;
|
||||
printf("%f\n", *(float*)point);
|
||||
point+=4;
|
||||
printf("%d\n", *(uint32_t*)point);
|
||||
point+=4;
|
||||
printf("%c\n", *(char*)point);
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
#ifndef PODATKI
|
||||
#define PODATKI
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint16_t* rezerviraj(int velikostZlogi);
|
||||
|
||||
void brisi(uint16_t* pomnilnik);
|
||||
|
||||
uint16_t* vstavi(uint16_t* pomnilnik);
|
||||
|
||||
void izpis(uint16_t* pomnilnik);
|
||||
|
||||
#endif
|
@@ -0,0 +1,18 @@
|
||||
all: build run
|
||||
|
||||
debug: buildd run clean
|
||||
|
||||
zip:
|
||||
zip naloga.zip main.c Makefile pretvori.c pretvori.h
|
||||
|
||||
build: main.c pretvori.c pretvori.h
|
||||
gcc -m32 main.c pretvori.c -o demo_pretvori
|
||||
|
||||
buildd: main.c pretvori.c pretvori.h
|
||||
gcc -g -m32 main.c pretvori.c -o demo_pretvori -fsanitize=address -fno-omit-frame-pointer
|
||||
|
||||
run:
|
||||
./demo_pretvori 80
|
||||
|
||||
clean:
|
||||
rm -f demo_pretvori
|
18
semester_4/namenska_programska_oprema/Naloga_1/Vaja_2/main.c
Normal file
18
semester_4/namenska_programska_oprema/Naloga_1/Vaja_2/main.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "pretvori.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 2) {
|
||||
printf("Ni dovolj argumentov");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unicode = preberiVhod(argv);
|
||||
|
||||
int utf8 = pretvoriZnak(unicode);
|
||||
izpisiZnak(utf8);
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "pretvori.h"
|
||||
|
||||
int preberiVhod(char* cmd[])
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
int len = strlen(cmd[1]);
|
||||
uint8_t hex = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if(cmd[1][i] >= '0' && cmd[1][i] <= '9')
|
||||
{
|
||||
hex = cmd[1][i] - '0';
|
||||
}
|
||||
else if (cmd[1][i] >= 'A' && cmd[1][i] <= 'F')
|
||||
{
|
||||
hex = cmd[1][i] - 'A' + 10;
|
||||
}
|
||||
ret = ret << 4;
|
||||
ret = ret | hex;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pretvoriZnak(int znak)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(znak <= 0x7F)
|
||||
{
|
||||
return znak;
|
||||
}
|
||||
|
||||
if(znak <= 0x7FF)
|
||||
{
|
||||
//110xxxxx10xxxxxx
|
||||
ret = 0b1100000010000000;
|
||||
uint32_t mask1 = 0b111111;
|
||||
ret = ret | (znak & mask1);
|
||||
uint32_t mask2 = 0b1111100000000;
|
||||
ret = ret | ((znak << 2) & mask2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//if((znak >> 13) == 0b110)
|
||||
|
||||
|
||||
if(znak <= 0xFFFF)
|
||||
{
|
||||
//1110xxxx10xxxxxx10xxxxxx
|
||||
ret = 0b111000001000000010000000;
|
||||
uint32_t mask1 = 0b111111;
|
||||
ret = ret | (znak & mask1);
|
||||
uint32_t mask2 = 0b11111100000000;
|
||||
ret = ret | ((znak << 2) & mask2);
|
||||
uint32_t mask3 = 0b11110000000000000000;
|
||||
ret = ret | ((znak << 4) & mask3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void izpisiZnak(int znak)
|
||||
{
|
||||
printf("UTF-8 binarno: ");
|
||||
|
||||
int firstZero = 0;
|
||||
if ( znak <= 0xFF ) firstZero = 7;
|
||||
else if (znak <= 0xFFFF ) firstZero = 15;
|
||||
else if (znak <= 0xFFFFFF ) firstZero = 23;
|
||||
|
||||
for (int i = firstZero; i >= 0; i--)
|
||||
{
|
||||
// Z bitshiftanjem pogledam ali je na mestu 1 ce je dobim neko stevilo vecje od 1 in zapisem 1
|
||||
int j = znak & (1 << i);
|
||||
printf("%d", (j>0)?1:0);
|
||||
if(i % 4 == 0) printf(" ");
|
||||
}
|
||||
|
||||
printf("\nUTF-8 hex: %X", znak);
|
||||
|
||||
printf("\n");
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
#ifndef PODATKI
|
||||
#define PODATKI
|
||||
|
||||
int preberiVhod(char* cmd[]);
|
||||
int pretvoriZnak(int znak);
|
||||
void izpisiZnak(int znak);
|
||||
|
||||
#endif
|
@@ -0,0 +1,21 @@
|
||||
all: build run
|
||||
|
||||
debug: buildd run clean
|
||||
|
||||
zip:
|
||||
zip naloga.zip main.c Makefile
|
||||
|
||||
build: main.c
|
||||
gcc -m32 -O3 main.c -o demo_client
|
||||
|
||||
buildd: main.c
|
||||
gcc -g -m32 main.c -o demo_client -fsanitize=address -fno-omit-frame-pointer
|
||||
|
||||
run:
|
||||
./demo_client localhost 8003 test1
|
||||
|
||||
clean:
|
||||
rm -f demo_client main
|
||||
|
||||
chm:
|
||||
chmod 755 script.sh
|
241
semester_4/namenska_programska_oprema/Naloga_2/Client/main.c
Normal file
241
semester_4/namenska_programska_oprema/Naloga_2/Client/main.c
Normal file
@@ -0,0 +1,241 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define MAXDATASIZE 1024
|
||||
#define DATOTEKA 2147483648
|
||||
#define MAPA 1073741824
|
||||
#define KONEC 0
|
||||
|
||||
typedef struct Data
|
||||
{
|
||||
uint32_t size;
|
||||
uint32_t type;
|
||||
char name[128];
|
||||
} Data;
|
||||
|
||||
int isDir(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
stat(path, &path_stat);
|
||||
return S_ISDIR(path_stat.st_mode);
|
||||
}
|
||||
|
||||
void sendFile(int sockfd, const char *fileName)
|
||||
{
|
||||
struct stat st;
|
||||
stat(fileName, &st);
|
||||
|
||||
Data dataS;
|
||||
dataS.size = st.st_size;
|
||||
dataS.type = DATOTEKA;
|
||||
memset(dataS.name, '\0', sizeof(dataS.name));
|
||||
strcpy(dataS.name, fileName);
|
||||
|
||||
if (send(sockfd, &dataS, sizeof(dataS), 0) < 0)
|
||||
{
|
||||
perror("send");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *ptr = fopen(fileName, "rb");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
perror("File");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buffer[MAXDATASIZE];
|
||||
size_t bytesRead = 0;
|
||||
while (bytesRead < st.st_size)
|
||||
{
|
||||
size_t read = fread(buffer, 1, sizeof(buffer), ptr);
|
||||
|
||||
if (send(sockfd, buffer, read, 0) < 0)
|
||||
{
|
||||
perror("send");
|
||||
}
|
||||
bytesRead += read;
|
||||
}
|
||||
|
||||
fclose(ptr);
|
||||
|
||||
printf("USPEL\tZBIRKA\t%s\t%d\n", dataS.name, dataS.size);
|
||||
}
|
||||
|
||||
void sendDir(int sockfd, const char *folderName)
|
||||
{
|
||||
Data dataToSend;
|
||||
dataToSend.size = 0;
|
||||
dataToSend.type = MAPA;
|
||||
strcpy(dataToSend.name, folderName);
|
||||
|
||||
if (send(sockfd, &dataToSend, sizeof(dataToSend), 0) < 0)
|
||||
{
|
||||
perror("send");
|
||||
return;
|
||||
}
|
||||
printf("USPEL\tIMENIK\t%s\t%d\n", dataToSend.name, dataToSend.size);
|
||||
}
|
||||
|
||||
void reciveConferm(int sockfd)
|
||||
{
|
||||
uint8_t ret;
|
||||
if ((recv(sockfd, &ret, sizeof(ret), 0)) == -1)
|
||||
{
|
||||
perror("recv");
|
||||
}
|
||||
}
|
||||
|
||||
void sendEnd(int sockfd)
|
||||
{
|
||||
Data dataToSend;
|
||||
dataToSend.size = 0;
|
||||
dataToSend.type = KONEC;
|
||||
strcpy(dataToSend.name, "");
|
||||
|
||||
if (send(sockfd, &dataToSend, sizeof(dataToSend), 0) < 0)
|
||||
{
|
||||
perror("send");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void sendFullFile(int sockfd, char *input)
|
||||
{
|
||||
//nik/nik/nik.txt
|
||||
char *ptr = strtok(input, "/");
|
||||
char fileName[128];
|
||||
memset(fileName, '\0', sizeof(fileName));
|
||||
while (ptr != NULL)
|
||||
{
|
||||
strcat(fileName, ptr);
|
||||
|
||||
if (isDir(fileName))
|
||||
{
|
||||
sendDir(sockfd, fileName);
|
||||
strcat(fileName, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendFile(sockfd, fileName);
|
||||
}
|
||||
|
||||
reciveConferm(sockfd);
|
||||
|
||||
ptr = strtok(NULL, "/");
|
||||
}
|
||||
}
|
||||
|
||||
void sendFullDir(int sockfd, char *input)
|
||||
{
|
||||
char fileName[128];
|
||||
memset(fileName, '\0', sizeof(fileName));
|
||||
//nik/test
|
||||
char *ptr = strtok(input, "/");
|
||||
while (ptr != NULL)
|
||||
{
|
||||
strcat(fileName, ptr);
|
||||
|
||||
if (isDir(fileName))
|
||||
{
|
||||
sendDir(sockfd, fileName);
|
||||
strcat(fileName, "/");
|
||||
}
|
||||
reciveConferm(sockfd);
|
||||
|
||||
ptr = strtok(NULL, "/");
|
||||
}
|
||||
|
||||
struct dirent *files;
|
||||
DIR *dir = opendir(fileName);
|
||||
if (dir == NULL)
|
||||
{
|
||||
printf("Directory cannot be opened!");
|
||||
return;
|
||||
}
|
||||
//nik/test/nik.txt
|
||||
char srcName[128];
|
||||
while ((files = readdir(dir)) != NULL)
|
||||
{
|
||||
|
||||
if(strncmp( "..", files->d_name, 2) > -1) continue;
|
||||
if(strncmp( ".", files->d_name, 1) > -1) continue;
|
||||
strcpy(srcName, fileName);
|
||||
strcat(srcName, files->d_name);
|
||||
if (!isDir(srcName))
|
||||
{
|
||||
sendFile(sockfd, srcName);
|
||||
reciveConferm(sockfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendFullDir(sockfd, srcName);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
//write(0, "Uporaba: TCPtimec ime vrata datoteka\n\0", 29);
|
||||
printf("Uporaba: TCPtimec ime vrata datoteka\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int sockfd; // socekt file descriptor, new file descriptor
|
||||
struct hostent *he; // pointer to the structure hostent (returned by gethostbyname)
|
||||
struct sockaddr_in their_addr; // server address
|
||||
|
||||
// get the server IP address
|
||||
if ((he = gethostbyname(argv[1])) == NULL)
|
||||
{
|
||||
herror("gethostbyname"); // prints string + value of h_error variable [HOST_NOT_FOUND || NO_ADDRESS or NO_DATA || NO_RECOVERY || TRY_AGAIN]
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create socket
|
||||
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
their_addr.sin_family = AF_INET; // family to Address Family InterNET
|
||||
their_addr.sin_port = htons(atoi(argv[2])); // get server's port number - should be checked for input errors (not a number, etc.)
|
||||
their_addr.sin_addr = *((struct in_addr *)he->h_addr); // server's IP address from hostent structure pointed to by he variable...
|
||||
memset(&(their_addr.sin_zero), '\0', 8); // for conversion between structures only, a trick to ensure pointer casting...
|
||||
|
||||
// connect to the server... (no bind necessary as we are connecting to remote host... Kernel will find a free port for us and will bind it to sockfd)
|
||||
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
perror("connect");
|
||||
exit(1);
|
||||
}
|
||||
//nik
|
||||
if (isDir(argv[3]))
|
||||
{
|
||||
sendFullDir(sockfd, argv[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendFullFile(sockfd, argv[3]);
|
||||
}
|
||||
|
||||
sendEnd(sockfd);
|
||||
// close socket
|
||||
close(sockfd);
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
@@ -0,0 +1 @@
|
||||
test2
|
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
@@ -0,0 +1 @@
|
||||
test2
|
@@ -0,0 +1,21 @@
|
||||
all: build run
|
||||
|
||||
debug: buildd run clean
|
||||
|
||||
zip:
|
||||
zip naloga.zip main.c Makefile
|
||||
|
||||
build: main.c
|
||||
gcc -m32 -O3 main.c -o demo_streznik -pthread
|
||||
|
||||
buildd: main.c
|
||||
gcc -g -m32 main.c -o demo_streznik -fsanitize=address -fno-omit-frame-pointer
|
||||
|
||||
run:
|
||||
./demo_streznik 8003
|
||||
|
||||
clean:
|
||||
rm -f demo_streznik
|
||||
|
||||
cleanAll:
|
||||
rm -f img.jpg text.txt Video1.mp4 Video2.mp4
|
160
semester_4/namenska_programska_oprema/Naloga_2/Server/main.c
Normal file
160
semester_4/namenska_programska_oprema/Naloga_2/Server/main.c
Normal file
@@ -0,0 +1,160 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXDATASIZE 1024
|
||||
#define DATOTEKA 2
|
||||
#define MAPA 1
|
||||
#define KONEC 0
|
||||
|
||||
typedef struct Data
|
||||
{
|
||||
uint32_t sizeOfFile;
|
||||
uint32_t type;
|
||||
char fileName[128];
|
||||
} Data;
|
||||
|
||||
void reciveFile(int newfd, Data data)
|
||||
{
|
||||
uint8_t buffer[MAXDATASIZE];
|
||||
int numbytes = 0;
|
||||
FILE *wptr = fopen(data.fileName, "wb");
|
||||
size_t bytesRecived = 0;
|
||||
while (bytesRecived < data.sizeOfFile)
|
||||
{
|
||||
if ((numbytes = recv(newfd, buffer, MAXDATASIZE, 0)) == -1)
|
||||
{
|
||||
perror("recv");
|
||||
return;
|
||||
}
|
||||
fwrite(buffer, numbytes, 1, wptr);
|
||||
bytesRecived += numbytes;
|
||||
}
|
||||
fclose(wptr);
|
||||
}
|
||||
|
||||
void sendConf(int newfd)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
if (send(newfd, &ret, sizeof(ret), 0) < 0)
|
||||
{
|
||||
perror("send1");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void reciveFolder(Data data)
|
||||
{
|
||||
mkdir(data.fileName, 0777);
|
||||
}
|
||||
|
||||
void *recive(void *fd)
|
||||
{
|
||||
int newfd = *(int *)fd;
|
||||
int exit = 0;
|
||||
while (1)
|
||||
{
|
||||
|
||||
Data recivedData;
|
||||
if ((recv(newfd, &recivedData, sizeof(recivedData), 0)) == -1)
|
||||
{
|
||||
perror("recv");
|
||||
// exit(1);
|
||||
}
|
||||
|
||||
switch (recivedData.type)
|
||||
{
|
||||
case DATOTEKA:
|
||||
reciveFile(newfd, recivedData);
|
||||
printf("USPEL\tZBIRKA\t%s\t%d\n", recivedData.fileName, recivedData.sizeOfFile);
|
||||
break;
|
||||
case MAPA:
|
||||
reciveFolder(recivedData);
|
||||
printf("USPEL\tIMENIK\t%s\t%d\n", recivedData.fileName, recivedData.sizeOfFile);
|
||||
break;
|
||||
case KONEC:
|
||||
close(newfd);
|
||||
exit = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (exit)
|
||||
break;
|
||||
sendConf(newfd);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int sockfd; // socekt file descriptor, new file descriptor
|
||||
socklen_t length; // socket length (length of clinet address)
|
||||
struct sockaddr_in saddr, caddr; // server address, client address
|
||||
time_t itime; // time format
|
||||
char *tstr; // var holding the string to be send via TCP
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Uporaba: demo_client vrata (vrata 0-1024 so rezervirana za jedro)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create socket
|
||||
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror("socket");
|
||||
}
|
||||
|
||||
saddr.sin_family = AF_INET; // IPv4
|
||||
saddr.sin_addr.s_addr = INADDR_ANY; // localhost
|
||||
saddr.sin_port = htons(atoi(argv[1])); // port converted from ascii to integer
|
||||
|
||||
// binds the socket file description to the actual port (similar to open)
|
||||
if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
|
||||
{
|
||||
perror("bind");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// start listening on the given port
|
||||
if (listen(sockfd, 0) < 0)
|
||||
{
|
||||
perror("listen");
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = sizeof(caddr); // length of client address
|
||||
|
||||
pthread_t thread_id[10];
|
||||
int newfd[10];
|
||||
uint8_t kaz = 0;
|
||||
while (1)
|
||||
{
|
||||
|
||||
if ((newfd[kaz] = accept(sockfd, (struct sockaddr *)&caddr, &length)) < 0)
|
||||
{
|
||||
perror("accept");
|
||||
return 0;
|
||||
}
|
||||
recive(newfd);
|
||||
pthread_create(&thread_id[kaz], NULL, recive, &newfd[kaz]);
|
||||
// recive(newfd[kaz]);
|
||||
kaz++;
|
||||
kaz = kaz % 10;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
{
|
||||
pthread_join(thread_id[i], NULL);
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
|
||||
return 0;
|
||||
}
|
28
semester_4/namenska_programska_oprema/Naloga_3/Makefile
Normal file
28
semester_4/namenska_programska_oprema/Naloga_3/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
all: build run
|
||||
|
||||
zip:
|
||||
zip naloga.zip main.c Makefile
|
||||
|
||||
build: main.o
|
||||
ld -m elf_i386 main.o \
|
||||
/usr/lib32/crt1.o \
|
||||
/usr/lib32/crti.o \
|
||||
/usr/lib32/crtn.o \
|
||||
-dynamic-linker \
|
||||
/usr/lib32/ld-linux.so.2 \
|
||||
-lc -o hello \
|
||||
|
||||
run: hello
|
||||
./hello
|
||||
|
||||
clean:
|
||||
rm -f hello main.i main.s main.o
|
||||
|
||||
build_i: main.c
|
||||
cpp -m32 main.c -o main.i
|
||||
|
||||
build_s: main.i
|
||||
gcc -S -m32 main.i -o main.s
|
||||
|
||||
build_o: main.s
|
||||
as -32 main.s -o main.o
|
7
semester_4/namenska_programska_oprema/Naloga_3/main.c
Normal file
7
semester_4/namenska_programska_oprema/Naloga_3/main.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
return 0;
|
||||
}
|
23
semester_4/namenska_programska_oprema/Naloga_4/Makefile
Normal file
23
semester_4/namenska_programska_oprema/Naloga_4/Makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
all: build run
|
||||
|
||||
debug: buildd run clean
|
||||
|
||||
zip:
|
||||
zip naloga.zip hello.c Makefile fun.c fun.h main.c
|
||||
|
||||
build: build_hello build_elf_changer
|
||||
|
||||
build_hello: hello.c
|
||||
gcc -m32 hello.c -o hello
|
||||
|
||||
buildd: main.c fun.c
|
||||
gcc -g -m32 main.c fun.c -o elf_changer -fsanitize=address -fno-omit-frame-pointer -Wall -Wextra -Wpedantic -Werror
|
||||
|
||||
build_elf_changer:
|
||||
gcc -m32 main.c fun.c -o elf_changer -Wall -Wextra -Wpedantic -Werror
|
||||
|
||||
run:
|
||||
./elf_changer -h hello
|
||||
|
||||
clean:
|
||||
rm -f hello elf_changer
|
299
semester_4/namenska_programska_oprema/Naloga_4/fun.c
Normal file
299
semester_4/namenska_programska_oprema/Naloga_4/fun.c
Normal file
@@ -0,0 +1,299 @@
|
||||
#include "fun.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void printElf(const char *fileName)
|
||||
{
|
||||
FILE *fp = fopen(fileName, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("Error: cannot open file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Elf32_Ehdr ehdr;
|
||||
|
||||
fread(&ehdr, sizeof(Elf32_Ehdr), 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
printf("ELF header:\n");
|
||||
|
||||
printf(" Magic number:\t\t\t\t\t\t%02x %02x %02x %02x\n", ehdr.e_ident[0], ehdr.e_ident[1], ehdr.e_ident[2], ehdr.e_ident[3]);
|
||||
|
||||
printf(" Class:\t\t\t\t\t\t");
|
||||
switch (ehdr.e_ident[EI_CLASS])
|
||||
{
|
||||
case ELFCLASSNONE:
|
||||
printf("Invalid class\n");
|
||||
break;
|
||||
case ELFCLASS32:
|
||||
printf("ELF32\n");
|
||||
break;
|
||||
case ELFCLASS64:
|
||||
printf("ELF64\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown class (0x%x)\n", ehdr.e_ident[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Data:\t\t\t\t\t\t\t");
|
||||
switch (ehdr.e_ident[EI_DATA])
|
||||
{
|
||||
case ELFDATANONE:
|
||||
printf("Invalid data encoding\n");
|
||||
break;
|
||||
case ELFDATA2LSB:
|
||||
printf("2's complement, little endian\n");
|
||||
break;
|
||||
case ELFDATA2MSB:
|
||||
printf("2's complement, big endian\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown data encoding (0x%x)\n", ehdr.e_ident[5]);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Version:\t\t\t\t\t\t");
|
||||
switch (ehdr.e_ident[EI_VERSION])
|
||||
{
|
||||
case EV_NONE:
|
||||
printf("Invalid version\n");
|
||||
break;
|
||||
case EV_CURRENT:
|
||||
printf("Current version\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown version (0x%x)\n", ehdr.e_ident[6]);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" OS/ABI:\t\t\t\t\t\t");
|
||||
switch (ehdr.e_ident[EI_OSABI])
|
||||
{
|
||||
case ELFOSABI_NONE:
|
||||
printf("UNIX System V ABI\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown OS/ABI (0x%x)\n", ehdr.e_ident[7]);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" ABI Version:\t\t\t\t\t\t%d\n", ehdr.e_ident[EI_ABIVERSION]);
|
||||
|
||||
printf(" Type:\t\t\t\t\t\t\t");
|
||||
switch (ehdr.e_type)
|
||||
{
|
||||
case ET_NONE:
|
||||
printf("No file type\n");
|
||||
break;
|
||||
case ET_REL:
|
||||
printf("Relocatable file\n");
|
||||
break;
|
||||
case ET_EXEC:
|
||||
printf("Executable file\n");
|
||||
break;
|
||||
case ET_DYN:
|
||||
printf("Shared object file\n");
|
||||
break;
|
||||
case ET_CORE:
|
||||
printf("Core file\n");
|
||||
break;
|
||||
case ET_LOPROC:
|
||||
printf("Processor-specific\n");
|
||||
break;
|
||||
case ET_HIPROC:
|
||||
printf("Processor-specific\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown type (0x%x)\n", ehdr.e_type);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Machine:\t\t\t\t\t\t");
|
||||
switch (ehdr.e_machine)
|
||||
{
|
||||
case EM_386:
|
||||
printf("Intel 80386\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown type (0x%x)\n", ehdr.e_type);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Version:\t\t\t\t\t\t0x%x\n", ehdr.e_version);
|
||||
|
||||
printf(" Entry point address:\t\t\t\t\t0x%x\n", ehdr.e_entry);
|
||||
|
||||
printf(" Start of program headers:\t\t\t\t%d (bytes into file)\n", ehdr.e_phoff);
|
||||
|
||||
printf(" Start of section headers:\t\t\t\t%d (bytes into file)\n", ehdr.e_shoff);
|
||||
|
||||
printf(" Flags:\t\t\t\t\t\t0x%x\n", ehdr.e_flags);
|
||||
|
||||
printf(" Size of this header:\t\t\t\t\t%d (bytes)\n", ehdr.e_ehsize);
|
||||
|
||||
printf(" Size of program headers:\t\t\t\t%d (bytes)\n", ehdr.e_phentsize);
|
||||
|
||||
printf(" Number of program headers:\t\t\t\t%d\n", ehdr.e_phnum);
|
||||
|
||||
printf(" Size of section headers:\t\t\t\t%d (bytes)\n", ehdr.e_shentsize);
|
||||
|
||||
printf(" Number of section headers:\t\t\t\t%d \n", ehdr.e_shnum);
|
||||
|
||||
printf(" Section header string table index:\t\t\t%d \n", ehdr.e_shstrndx);
|
||||
}
|
||||
|
||||
void printElfFunc(const char *fileName)
|
||||
{
|
||||
FILE *fd = fopen(fileName, "rb");
|
||||
|
||||
if (!fd)
|
||||
{
|
||||
perror("Failed to open file");
|
||||
return;
|
||||
}
|
||||
|
||||
Elf32_Ehdr ehdr;
|
||||
fread(&ehdr, sizeof(Elf32_Ehdr), 1, fd);
|
||||
fseek(fd, ehdr.e_shoff, SEEK_SET);
|
||||
|
||||
Elf32_Shdr simbolHdr;
|
||||
Elf32_Shdr stringHdr;
|
||||
uint8_t strtab = 0;
|
||||
for (size_t i = 0; i < ehdr.e_shnum; i++)
|
||||
{
|
||||
Elf32_Shdr shdr;
|
||||
fread(&shdr, sizeof(Elf32_Shdr), 1, fd);
|
||||
if (shdr.sh_type == SHT_SYMTAB)
|
||||
{
|
||||
simbolHdr = shdr;
|
||||
}
|
||||
else if (shdr.sh_type == SHT_STRTAB)
|
||||
{
|
||||
strtab++;
|
||||
if (strtab == 2)
|
||||
{
|
||||
stringHdr = shdr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t numOfSimbols = simbolHdr.sh_size / sizeof(Elf32_Sym);
|
||||
char name[20];
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
printf("%-10s%-10s %-10s%-20s\n", "NR", "Value", "Size", "Name");
|
||||
int pos = 0;
|
||||
for (size_t i = 0; i < numOfSimbols; i++)
|
||||
{
|
||||
fseek(fd, simbolHdr.sh_offset + i * sizeof(Elf32_Sym), SEEK_SET);
|
||||
Elf32_Sym sys;
|
||||
fread(&sys, sizeof(Elf32_Sym), 1, fd);
|
||||
|
||||
if (sys.st_size > 50)
|
||||
{
|
||||
printf("%-10d", pos++);
|
||||
printf("0x%-8x ", sys.st_value);
|
||||
printf("%-10d", sys.st_size);
|
||||
|
||||
fseek(fd, stringHdr.sh_offset + sys.st_name, SEEK_SET);
|
||||
fread(&name, sizeof(name), 1, fd);
|
||||
|
||||
printf("%-20s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
void changeElf(int argc, const char **argv)
|
||||
{
|
||||
FILE *fd = fopen(argv[2], "r+b");
|
||||
if (!fd)
|
||||
{
|
||||
perror("Failed to open file");
|
||||
return;
|
||||
}
|
||||
|
||||
Elf32_Ehdr ehdr;
|
||||
fread(&ehdr, sizeof(Elf32_Ehdr), 1, fd);
|
||||
fseek(fd, ehdr.e_shoff, SEEK_SET);
|
||||
|
||||
Elf32_Shdr simbolHdr;
|
||||
Elf32_Shdr stringHdr;
|
||||
uint8_t strtab = 0;
|
||||
for (size_t i = 0; i < ehdr.e_shnum; i++)
|
||||
{
|
||||
Elf32_Shdr shdr;
|
||||
fread(&shdr, sizeof(Elf32_Shdr), 1, fd);
|
||||
if (shdr.sh_type == SHT_SYMTAB)
|
||||
{
|
||||
simbolHdr = shdr;
|
||||
}
|
||||
else if (shdr.sh_type == SHT_STRTAB)
|
||||
{
|
||||
strtab++;
|
||||
if (strtab == 2)
|
||||
{
|
||||
stringHdr = shdr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t numOfSimbols = simbolHdr.sh_size / sizeof(Elf32_Sym);
|
||||
char name[20];
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
printf("%-10s\t%s\t\t%s\t%s\t\n", "IME", "NASLOV", "VREDNOST", "NOVA_VREDNOST");
|
||||
|
||||
for (unsigned int i = 0; i < numOfSimbols; ++i)
|
||||
{
|
||||
fseek(fd, simbolHdr.sh_offset + i * sizeof(Elf32_Sym), SEEK_SET);
|
||||
Elf32_Sym sys;
|
||||
fread(&sys, sizeof(Elf32_Sym), 1, fd);
|
||||
|
||||
if (!(ELF32_ST_TYPE(sys.st_info) == STT_OBJECT && ELF32_ST_BIND(sys.st_info) == STB_GLOBAL))
|
||||
continue;
|
||||
|
||||
fseek(fd, stringHdr.sh_offset + sys.st_name, SEEK_SET);
|
||||
fread(&name, sizeof(name), 1, fd);
|
||||
|
||||
int con = 1;
|
||||
for (int j = 3; j < argc; j++)
|
||||
{
|
||||
if (strcmp(name, argv[j]) == 0)
|
||||
{
|
||||
con = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (con)
|
||||
continue;
|
||||
|
||||
printf("%-10s\t", name);
|
||||
printf("%x\t\t", sys.st_value);
|
||||
|
||||
fseek(fd, ehdr.e_shoff + sys.st_shndx * sizeof(Elf32_Shdr), SEEK_SET);
|
||||
Elf32_Shdr hdr;
|
||||
fread(&hdr, sizeof(Elf32_Shdr), 1, fd);
|
||||
uint32_t realAddr = (sys.st_value - hdr.sh_addr) + hdr.sh_offset;
|
||||
|
||||
fseek(fd, realAddr, SEEK_SET);
|
||||
uint32_t val;
|
||||
fread(&val, sizeof(uint32_t), 1, fd);
|
||||
|
||||
printf("%x\t\t", val);
|
||||
|
||||
val += 10;
|
||||
fseek(fd, realAddr, SEEK_SET);
|
||||
fwrite(&val, sizeof(val), 1, fd);
|
||||
printf("%x\n", val);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
return;
|
||||
}
|
4
semester_4/namenska_programska_oprema/Naloga_4/fun.h
Normal file
4
semester_4/namenska_programska_oprema/Naloga_4/fun.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <elf.h>
|
||||
void printElf(const char *fileName);
|
||||
void printElfFunc(const char *fileName);
|
||||
void changeElf(int argc, const char **argv);
|
18
semester_4/namenska_programska_oprema/Naloga_4/hello.c
Normal file
18
semester_4/namenska_programska_oprema/Naloga_4/hello.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int funkcija(int a)
|
||||
{
|
||||
return a + 1;
|
||||
}
|
||||
|
||||
int g1;
|
||||
int g2 = 10;
|
||||
int g3 = 14;
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Vrednost g1: %d\n", g1);
|
||||
printf("Vrednost g2: %d\n", g2);
|
||||
printf("Vrednost g3: %d\n", g3);
|
||||
return 0;
|
||||
}
|
32
semester_4/namenska_programska_oprema/Naloga_4/main.c
Normal file
32
semester_4/namenska_programska_oprema/Naloga_4/main.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "fun.h"
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
printf("Usage: %s [-hcl] <elf_path> \n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char var = argv[1][1];
|
||||
|
||||
if (var == 'h')
|
||||
{
|
||||
printElf(argv[2]);
|
||||
}
|
||||
else if (var == 'i')
|
||||
{
|
||||
printElfFunc(argv[2]);
|
||||
}
|
||||
else if (var == 'c')
|
||||
{
|
||||
changeElf(argc, argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("You entered something else\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint32_t sestej(uint32_t a, uint32_t b);
|
||||
void niz_veliki(char* niz);
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint32_t sestej(uint32_t a, uint32_t b);
|
||||
void niz_veliki(char* niz);
|
@@ -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;
|
||||
}
|
@@ -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
|
BIN
semester_4/namenska_programska_oprema/Naloga_5/staticno/libXPO.a
Normal file
BIN
semester_4/namenska_programska_oprema/Naloga_5/staticno/libXPO.a
Normal file
Binary file not shown.
@@ -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;
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint32_t sestej(uint32_t a, uint32_t b);
|
||||
void niz_veliki(char* niz);
|
BIN
semester_4/namenska_programska_oprema/Naloga_5/staticno/libXPO.o
Normal file
BIN
semester_4/namenska_programska_oprema/Naloga_5/staticno/libXPO.o
Normal file
Binary file not shown.
@@ -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;
|
||||
}
|
51
semester_4/namenska_programska_oprema/Naloga_5/ukazi.txt
Normal file
51
semester_4/namenska_programska_oprema/Naloga_5/ukazi.txt
Normal 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
|
18
semester_4/namenska_programska_oprema/Naloga_5/vaje/Makefile
Normal file
18
semester_4/namenska_programska_oprema/Naloga_5/vaje/Makefile
Normal 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
|
||||
|
@@ -0,0 +1,5 @@
|
||||
# Knjižnice
|
||||
|
||||
## Prevajanje in vključevanje zunanjih modulov
|
||||
|
||||
Za demonstracijo preverite zbirko ukazi.txt.
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
529
semester_4/namenska_programska_oprema/Naloga_5/vaje/ukazi.txt
Normal file
529
semester_4/namenska_programska_oprema/Naloga_5/vaje/ukazi.txt
Normal 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. 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
|
29
semester_4/namenska_programska_oprema/Naloga_6/Makefile
Normal file
29
semester_4/namenska_programska_oprema/Naloga_6/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
obj-m += xpo_modul.o
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
||||
|
||||
load:
|
||||
sudo insmod xpo_modul.ko
|
||||
|
||||
unload:
|
||||
sudo rmmod xpo_modul
|
||||
|
||||
list:
|
||||
sudo lsmod | grep xpo
|
||||
|
||||
msg:
|
||||
sudo dmesg | grep xpo
|
||||
|
||||
start:
|
||||
sudo watch -n 0.2 "cat /dev/xpo_modul"
|
||||
|
||||
restart: msg unload build load
|
||||
|
||||
zip:
|
||||
zip naloga.zip Makefile xpo_modul.c xpo_modul.h
|
116
semester_4/namenska_programska_oprema/Naloga_6/xpo_modul.c
Normal file
116
semester_4/namenska_programska_oprema/Naloga_6/xpo_modul.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h> /* for sprintf() */
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/types.h>
|
||||
#include"xpo_modul.h"
|
||||
|
||||
MODULE_AUTHOR("NIKOLA");
|
||||
MODULE_DESCRIPTION("Simple kernel driver skeleton");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
static int major; // major number of device driver
|
||||
#define DEVICE_NAME "xpo_modul"
|
||||
|
||||
static struct class *cls;
|
||||
|
||||
static int __init xpo_driver_init(void)
|
||||
{
|
||||
pr_info("xpo: driver INIT\n");
|
||||
|
||||
major = register_chrdev(0, DEVICE_NAME, &xpo_fops);
|
||||
|
||||
if (major < 0) {
|
||||
pr_alert("xpo: registering char device failed with %d\n", major);
|
||||
return major;
|
||||
} else {
|
||||
pr_info("xpo: registering char device %d\n", major);
|
||||
}
|
||||
|
||||
cls = class_create(THIS_MODULE, DEVICE_NAME);
|
||||
|
||||
device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
|
||||
|
||||
pr_info("xpo: Device created on /dev/%s\n", DEVICE_NAME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xpo_driver_exit(void)
|
||||
{
|
||||
pr_info("xpo: driver EXIT\n");
|
||||
|
||||
device_destroy(cls, MKDEV(major, 0));
|
||||
|
||||
class_destroy(cls);
|
||||
|
||||
unregister_chrdev(major, DEVICE_NAME);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
module_init(xpo_driver_init);
|
||||
module_exit(xpo_driver_exit);
|
||||
|
||||
// abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
static unsigned char xpo_map[256] =
|
||||
{
|
||||
[0 ... 255] = 0,
|
||||
|
||||
[2] = '1',
|
||||
[3] = '2',
|
||||
[4] = '3',
|
||||
[5] = '4',
|
||||
[6] = '5',
|
||||
[7] = '6',
|
||||
[8] = '7',
|
||||
[9] = '8',
|
||||
[10] = '9',
|
||||
[11] = '0',
|
||||
|
||||
[16] = 'q',
|
||||
[17] = 'w',
|
||||
[18] = 'e',
|
||||
[19] = 'r',
|
||||
[20] = 't',
|
||||
[21] = 'z',
|
||||
[22] = 'u',
|
||||
[23] = 'i',
|
||||
[24] = 'o',
|
||||
[25] = 'p',
|
||||
|
||||
[30] = 'a',
|
||||
[31] = 's',
|
||||
[32] = 'd',
|
||||
[33] = 'f',
|
||||
[34] = 'g',
|
||||
[35] = 'h',
|
||||
[36] = 'j',
|
||||
[37] = 'k',
|
||||
[37] = 'l',
|
||||
|
||||
[44] = 'y',
|
||||
[45] = 'x',
|
||||
[46] = 'c',
|
||||
[47] = 'v',
|
||||
[48] = 'b',
|
||||
[49] = 'n',
|
||||
[50] = 'm'
|
||||
};
|
||||
|
||||
ssize_t xpo_read(struct file *filep, char *buff, size_t count, loff_t *offp )
|
||||
{
|
||||
unsigned char c = inb(0x60); // 0x60 - which key down
|
||||
char buf[20];
|
||||
sprintf(buf, "%u - znak: %c", c, xpo_map[c]);
|
||||
|
||||
printk("xpo - signal: %s\n", buf);
|
||||
|
||||
return 0;
|
||||
}
|
20
semester_4/namenska_programska_oprema/Naloga_6/xpo_modul.h
Normal file
20
semester_4/namenska_programska_oprema/Naloga_6/xpo_modul.h
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
#ifndef _MY_DEVICE_H
|
||||
#define _MY_DEVICE_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/segment.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
ssize_t xpo_read(struct file *filep, char *buff, size_t count, loff_t *offp );
|
||||
|
||||
struct file_operations xpo_fops={
|
||||
read: xpo_read,
|
||||
};
|
||||
|
||||
#endif
|
27
semester_4/namenska_programska_oprema/Naloga_7/Makefile
Normal file
27
semester_4/namenska_programska_oprema/Naloga_7/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
obj-m += xpo_xor_module.o
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
||||
|
||||
load:
|
||||
sudo insmod xpo_xor_module.ko
|
||||
|
||||
unload:
|
||||
sudo rmmod xpo_xor_module
|
||||
|
||||
read:
|
||||
sudo cat /dev/xpo_xor_module
|
||||
|
||||
write1:
|
||||
sudo echo "NikolaJeVelik" > /dev/xpo_xor_module
|
||||
|
||||
write2:
|
||||
sudo echo "1234567890NikolaJeVelokMozKiHodiNaFaksInJeVMariboruInSedajDelaNalogoSajmujedolgcajtinbirajepocelkajdrugega" > /dev/xpo_xor_module
|
||||
|
||||
zip:
|
||||
zip naloga.zip Makefile xpo_xor_module.c xpo_xor_module.h
|
170
semester_4/namenska_programska_oprema/Naloga_7/xpo_xor_module.c
Normal file
170
semester_4/namenska_programska_oprema/Naloga_7/xpo_xor_module.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* xpo_xor_module.c: Creates a read-only char device that says how many times
|
||||
* you have read from the dev file
|
||||
*/
|
||||
#include "xpo_xor_module.h"
|
||||
|
||||
/* Prototypes - this would normally go in a .h file */
|
||||
static int device_open(struct inode *, struct file *);
|
||||
static int device_release(struct inode *, struct file *);
|
||||
static ssize_t device_read(struct file *, char __user *, size_t, loff_t *);
|
||||
static ssize_t device_write(struct file *, const char __user *, size_t, loff_t *);
|
||||
|
||||
#define SUCCESS 0
|
||||
#define DEVICE_NAME "xpo_xor_module" /* Dev name as it appears in /proc/devices */
|
||||
#define BUF_LEN 80 /* Max length of the message from the device */
|
||||
|
||||
/* Global variables are declared as static, so are global within the file. */
|
||||
static int major; /* major number assigned to our device driver */
|
||||
|
||||
enum {
|
||||
CDEV_NOT_USED = 0,
|
||||
CDEV_EXCLUSIVE_OPEN = 1,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Is device open? Used to prevent multiple access to device */
|
||||
static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED);
|
||||
|
||||
static char message[BUF_LEN + 1]; /* The message the device will give when asked */
|
||||
static struct class *cls;
|
||||
|
||||
static int __init xpo_xor_module_init(void)
|
||||
{
|
||||
major = register_chrdev(0, DEVICE_NAME, &xpo_xor_module_fops);
|
||||
if (major < 0) {
|
||||
pr_alert("Registering char device failed with %d\n", major);
|
||||
return major;
|
||||
}
|
||||
|
||||
pr_info("I was assigned major number %d.\n", major);
|
||||
|
||||
cls = class_create(THIS_MODULE, DEVICE_NAME);
|
||||
|
||||
device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
|
||||
|
||||
sprintf(message, "I already told you %d times Hello world!\n", 1);
|
||||
|
||||
pr_info("Device created on /dev/%s\n", DEVICE_NAME);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void __exit xpo_xor_module_exit(void)
|
||||
{
|
||||
device_destroy(cls, MKDEV(major, 0));
|
||||
|
||||
class_destroy(cls);
|
||||
|
||||
/* Unregister the device */
|
||||
unregister_chrdev(major, DEVICE_NAME);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
/* Called when a process tries to open the device file, like
|
||||
* "sudo cat /dev/xpo_xor_module"
|
||||
*/
|
||||
|
||||
static int device_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
|
||||
if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN))
|
||||
return -EBUSY;
|
||||
|
||||
|
||||
|
||||
try_module_get(THIS_MODULE);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called when a process closes the device file. */
|
||||
static int device_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
/* We're now ready for our next caller */
|
||||
atomic_set(&already_open, CDEV_NOT_USED);
|
||||
/* Decrement the usage count, or else once you opened the file, you will
|
||||
* never get rid of the module.
|
||||
*/
|
||||
|
||||
module_put(THIS_MODULE);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called when a process, which already opened the dev file, attempts to
|
||||
* read from it.
|
||||
*/
|
||||
|
||||
static ssize_t device_read(struct file *filp,
|
||||
char __user *buffer, /* buffer to fill with data */
|
||||
size_t length, /* length of the buffer */
|
||||
loff_t *offset)
|
||||
|
||||
{
|
||||
/* Number of bytes actually written to the buffer */
|
||||
int bytes_read = 0;
|
||||
const char *message_ptr = message;
|
||||
|
||||
if (!*(message_ptr + *offset)) { /* we are at the end of message */
|
||||
*offset = 0; /* reset the offset */
|
||||
return 0; /* signify end of file */
|
||||
}
|
||||
|
||||
message_ptr += *offset;
|
||||
/* Actually put the data into the buffer */
|
||||
|
||||
while (length && *message_ptr) {
|
||||
/* The buffer is in the user data segment, not the kernel
|
||||
* segment so "*" assignment won't work. We have to use
|
||||
* put_user which copies data from the kernel data segment to
|
||||
* the user data segment.
|
||||
*/
|
||||
put_user(*(message_ptr++), buffer++);
|
||||
|
||||
length--;
|
||||
|
||||
bytes_read++;
|
||||
}
|
||||
*offset += bytes_read;
|
||||
/* Most read functions return the number of bytes put into the buffer. */
|
||||
return bytes_read;
|
||||
}
|
||||
static int xpo_msg_location = 0;
|
||||
|
||||
static uint8_t xpo_key[5] = {2,6,1,3,2};
|
||||
static uint8_t xpo_key_location = 0;
|
||||
static ssize_t device_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
get_user(message[xpo_msg_location], buffer + i);
|
||||
|
||||
message[xpo_msg_location] ^= xpo_key[xpo_key_location];
|
||||
|
||||
xpo_key_location++;
|
||||
if(xpo_key_location > 5) xpo_key_location = 0;
|
||||
|
||||
xpo_msg_location++;
|
||||
if(xpo_msg_location > BUF_LEN - 1) xpo_msg_location = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
module_init(xpo_xor_module_init);
|
||||
module_exit(xpo_xor_module_exit);
|
||||
MODULE_LICENSE("GPL");
|
@@ -0,0 +1,30 @@
|
||||
|
||||
#ifndef _MY_DEVICE_H
|
||||
#define _MY_DEVICE_H
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h> /* for sprintf() */
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h> /* for get_user and put_user */
|
||||
#include <asm/errno.h>
|
||||
|
||||
static int device_open(struct inode *, struct file *);
|
||||
static int device_release(struct inode *, struct file *);
|
||||
static ssize_t device_read(struct file *, char __user *, size_t, loff_t *);
|
||||
static ssize_t device_write(struct file *, const char __user *, size_t, loff_t *);
|
||||
|
||||
static struct file_operations xpo_xor_module_fops = {
|
||||
.read = device_read,
|
||||
.write = device_write,
|
||||
.open = device_open,
|
||||
.release = device_release,
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user