diff options
Diffstat (limited to 'qemu_mode/libcompcov/pmparser.h')
-rw-r--r-- | qemu_mode/libcompcov/pmparser.h | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/qemu_mode/libcompcov/pmparser.h b/qemu_mode/libcompcov/pmparser.h new file mode 100644 index 00000000..34d0cd50 --- /dev/null +++ b/qemu_mode/libcompcov/pmparser.h @@ -0,0 +1,280 @@ +/* + @Author : ouadimjamal@gmail.com + @date : December 2015 + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. No representations are made about the suitability of this +software for any purpose. It is provided "as is" without express or +implied warranty. + + */ + +#ifndef H_PMPARSER +#define H_PMPARSER +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <linux/limits.h> + +//maximum line length in a procmaps file +#define PROCMAPS_LINE_MAX_LENGTH (PATH_MAX + 100) +/** + * procmaps_struct + * @desc hold all the information about an area in the process's VM + */ +typedef struct procmaps_struct{ + void* addr_start; //< start address of the area + void* addr_end; //< end address + unsigned long length; //< size of the range + + char perm[5]; //< permissions rwxp + short is_r; //< rewrote of perm with short flags + short is_w; + short is_x; + short is_p; + + long offset; //< offset + char dev[12]; //< dev major:minor + int inode; //< inode of the file that backs the area + + char pathname[600]; //< the path of the file that backs the area + //chained list + struct procmaps_struct* next; //<handler of the chinaed list +} procmaps_struct; + +/** + * procmaps_iterator + * @desc holds iterating information + */ +typedef struct procmaps_iterator{ + procmaps_struct* head; + procmaps_struct* current; +} procmaps_iterator; +/** + * pmparser_parse + * @param pid the process id whose memory map to be parser. the current process if pid<0 + * @return an iterator over all the nodes + */ +procmaps_iterator* pmparser_parse(int pid); + +/** + * pmparser_next + * @description move between areas + * @param p_procmaps_it the iterator to move on step in the chained list + * @return a procmaps structure filled with information about this VM area + */ +procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it); +/** + * pmparser_free + * @description should be called at the end to free the resources + * @param p_procmaps_it the iterator structure returned by pmparser_parse + */ +void pmparser_free(procmaps_iterator* p_procmaps_it); + +/** + * _pmparser_split_line + * @description internal usage + */ +void _pmparser_split_line(char*buf,char*addr1,char*addr2,char*perm, char* offset, char* device,char*inode,char* pathname); + +/** + * pmparser_print + * @param map the head of the list + * @order the order of the area to print, -1 to print everything + */ +void pmparser_print(procmaps_struct* map,int order); + + +/** + * gobal variables + */ +//procmaps_struct* g_last_head=NULL; +//procmaps_struct* g_current=NULL; + + +procmaps_iterator* pmparser_parse(int pid){ + procmaps_iterator* maps_it = malloc(sizeof(procmaps_iterator)); + char maps_path[500]; + if(pid>=0 ){ + sprintf(maps_path,"/proc/%d/maps",pid); + }else{ + sprintf(maps_path,"/proc/self/maps"); + } + FILE* file=fopen(maps_path,"r"); + if(!file){ + fprintf(stderr,"pmparser : cannot open the memory maps, %s\n",strerror(errno)); + return NULL; + } + int ind=0;char buf[PROCMAPS_LINE_MAX_LENGTH]; + //int c; + procmaps_struct* list_maps=NULL; + procmaps_struct* tmp; + procmaps_struct* current_node=list_maps; + char addr1[20],addr2[20], perm[8], offset[20], dev[10],inode[30],pathname[PATH_MAX]; + while( !feof(file) ){ + fgets(buf,PROCMAPS_LINE_MAX_LENGTH,file); + //allocate a node + tmp=(procmaps_struct*)malloc(sizeof(procmaps_struct)); + //fill the node + _pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname); + //printf("#%s",buf); + //printf("%s-%s %s %s %s %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname); + //addr_start & addr_end + //unsigned long l_addr_start; + sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start ); + sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end ); + //size + tmp->length=(unsigned long)(tmp->addr_end-tmp->addr_start); + //perm + strcpy(tmp->perm,perm); + tmp->is_r=(perm[0]=='r'); + tmp->is_w=(perm[1]=='w'); + tmp->is_x=(perm[2]=='x'); + tmp->is_p=(perm[3]=='p'); + + //offset + sscanf(offset,"%lx",&tmp->offset ); + //device + strcpy(tmp->dev,dev); + //inode + tmp->inode=atoi(inode); + //pathname + strcpy(tmp->pathname,pathname); + tmp->next=NULL; + //attach the node + if(ind==0){ + list_maps=tmp; + list_maps->next=NULL; + current_node=list_maps; + } + current_node->next=tmp; + current_node=tmp; + ind++; + //printf("%s",buf); + } + + //close file + fclose(file); + + + //g_last_head=list_maps; + maps_it->head = list_maps; + maps_it->current = list_maps; + return maps_it; +} + + +procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){ + if(p_procmaps_it->current == NULL) + return NULL; + procmaps_struct* p_current = p_procmaps_it->current; + p_procmaps_it->current = p_procmaps_it->current->next; + return p_current; + /* + if(g_current==NULL){ + g_current=g_last_head; + }else + g_current=g_current->next; + + return g_current; + */ +} + + + +void pmparser_free(procmaps_iterator* p_procmaps_it){ + procmaps_struct* maps_list = p_procmaps_it->head; + if(maps_list==NULL) return ; + procmaps_struct* act=maps_list; + procmaps_struct* nxt=act->next; + while(act!=NULL){ + free(act); + act=nxt; + if(nxt!=NULL) + nxt=nxt->next; + } + +} + + +void _pmparser_split_line( + char*buf,char*addr1,char*addr2, + char*perm,char* offset,char* device,char*inode, + char* pathname){ + // + int orig=0; + int i=0; + //addr1 + while(buf[i]!='-'){ + addr1[i-orig]=buf[i]; + i++; + } + addr1[i]='\0'; + i++; + //addr2 + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + addr2[i-orig]=buf[i]; + i++; + } + addr2[i-orig]='\0'; + + //perm + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + perm[i-orig]=buf[i]; + i++; + } + perm[i-orig]='\0'; + //offset + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + offset[i-orig]=buf[i]; + i++; + } + offset[i-orig]='\0'; + //dev + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + device[i-orig]=buf[i]; + i++; + } + device[i-orig]='\0'; + //inode + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + inode[i-orig]=buf[i]; + i++; + } + inode[i-orig]='\0'; + //pathname + pathname[0]='\0'; + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' ' && buf[i]!='\n'){ + pathname[i-orig]=buf[i]; + i++; + } + pathname[i-orig]='\0'; + +} + + +#endif |