You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
apex_dma_kvm_pub/vmread/pmparser.c

165 lines
3.3 KiB
C

4 years ago
#include "pmparser.h"
procmaps_struct* g_last_head = NULL;
procmaps_struct* g_current = NULL;
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;
while(buf[i]!='-'){
addr1[i-orig]=buf[i];
i++;
}
addr1[i]='\0';
i++;
orig=i;
while(buf[i]!='\t' && buf[i]!=' '){
addr2[i-orig]=buf[i];
i++;
}
addr2[i-orig]='\0';
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';
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';
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';
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[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';
}
/**
* pmparser_parse
* @param pid the process id whose memory map to be parser. the current process if pid<0
* @return list of procmaps_struct structers
*/
procmaps_struct* pmparser_parse(int pid){
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)
return NULL;
int ind=0;char buf[3000];
char 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[600];
while(1){
if( (c=(char)fgetc(file))==EOF ) break;
fgets(buf+1,259,file);
buf[0]=c;
tmp= (procmaps_struct*)malloc(sizeof(procmaps_struct));
_pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname);
sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start);
sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end);
tmp->length = ((unsigned long)tmp->addr_end - (unsigned long)tmp->addr_start);
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');
sscanf(offset,"%lx",(unsigned long*)&tmp->offset);
strcpy(tmp->dev,dev);
tmp->inode=atoi(inode);
strcpy(tmp->pathname,pathname);
tmp->next=NULL;
if(ind==0){
list_maps=tmp;
list_maps->next=NULL;
current_node=list_maps;
}
current_node->next=tmp;
current_node=tmp;
ind++;
}
g_last_head=list_maps;
return list_maps;
}
/**
* pmparser_next
* @description move between areas
*/
procmaps_struct* pmparser_next(){
if(g_last_head==NULL) return NULL;
if(g_current==NULL)
g_current=g_last_head;
else
g_current=g_current->next;
return g_current;
}
/**
* pmparser_free
* @description should be called at the end to free the resources
* @param maps_list the head of the list to be freed
*/
void pmparser_free(procmaps_struct* maps_list){
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;
}
}