/* try to support covertest * Authur Email: ovis_poly@sina.com * This file is part of GDB, but we use this as study purpose only This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" //in order to make command.h compiled #include "breakpoint.h" #include "command.h" // in order to use add_com #include "frame.h" #include "target.h" #include "ui-out.h" // in order to print message to UI #include #include #include #include "elf.h" #include "link.h" #include "value.h" #define MAIN_SIZE 0x1f4-0xbd +10 //typical size between first instruction and main #define ALL_BREAKPOINTS(B) for (B = breakpoint_chain; B; B = B->next) #define ALL_BREAKPOINTS_SAFE(B,TMP) \ for (B = breakpoint_chain; \ B ? (TMP=B->next, 1): 0; \ B = TMP) extern long lm_skip_pc; int coverTest=0; struct user_regs_struct oldregs; struct user oldcontext; extern ptid_t inferior_ptid; extern struct target_ops current_target; extern CORE_ADDR stop_pc; extern CORE_ADDR step_range_start; extern CORE_ADDR step_range_end; extern struct frame_info *current_frame; extern CORE_ADDR step_frame_address; extern struct breakpoint *breakpoint_chain; CORE_ADDR saved_step_frame_address; CORE_ADDR saved_step_sp; int cover_init_over = 0; char *coverPcBitMap=NULL; //1 long totalTextSize = 0; long runTextSize = 0; long lowestAddr=0, highestAddr=0; //set pc as run static int setPcAsRun(CORE_ADDR pc, CORE_ADDR start, CORE_ADDR end) { int i; if(pchighestAddr) // it is in shared lib { return 0; //don't record } if(coverPcBitMap[pc-lowestAddr] ==0) { coverPcBitMap[pc-lowestAddr]=1; return 1; } else { return 0; } } static void init_cover_bitmap() { long textSize=0; struct data_section_info_s *dataSection, *tempDS; struct section_table *p; int sectionFlag=0; if(cover_init_over==1) return; //get size of text segment for (p = current_target.to_sections; p < current_target.to_sections_end; p++) { sectionFlag = bfd_get_section_flags (p->bfd, p->the_bfd_section); if ( (sectionFlag & SEC_CODE) && (sectionFlag&SEC_READONLY) && (sectionFlag & SEC_LOAD) ) { if(strcmp(p->the_bfd_section->name,".init")!=0&& strcmp(p->the_bfd_section->name,".plt")!=0 && strcmp(p->the_bfd_section->name,".fini")!=0) { textSize+=p->endaddr - p->addr ; if(lowestAddr ==0) lowestAddr = p->addr; else { if(lowestAddr > p->addr) lowestAddr = p->addr; } if(highestAddr==0) highestAddr = p->endaddr; else { if(p->endaddr > highestAddr) highestAddr = p->endaddr; } } } } totalTextSize = textSize; //size in bit coverPcBitMap = (char *)malloc((highestAddr - lowestAddr)); memset(coverPcBitMap,0,highestAddr - lowestAddr); cover_init_over = 1; } static void cover_test(char *args, int from_tty) { int stepInstNum=0; double rate=0.0; CORE_ADDR start, end; if(!target_has_execution){ printf("target not start\n"); return; } //also change infrun.c normal_stop() to check this flag to not print source line info init_cover_bitmap(); coverTest=1; runTextSize=0; while(1) { if(!target_has_execution) break; find_pc_line_pc_range(stop_pc,&start,&end); if(setPcAsRun(stop_pc,start,end)==1) { if(lm_skip_pc!=0) //skip prologue { runTextSize+=lm_skip_pc; lm_skip_pc = 0; } stepInstNum++; runTextSize += end - start +1; } step_command(NULL,0); } //when the last pc is not even plus 1 coverTest=0; runTextSize = runTextSize - stepInstNum; if(!(runTextSize % 2)) runTextSize++; runTextSize+= MAIN_SIZE; rate=(double)runTextSize/(double)totalTextSize; printf("total coverage rate: %.2f\% \n",rate*100); free(coverPcBitMap); } _initialize_covertest (void) { struct cmd_list_element *c; //add command c = add_com("covertest",class_breakpoint,cover_test,"test cover"); }