void saveSharedLibrary::closeElf(){ elf_update(newElf, ELF_C_NULL); elf_update(newElf, ELF_C_WRITE); elf_end(newElf); P_close(newfd); }
/* * NAME: io_save() * DESCRIPTION: write a range of lines to a file */ bool io_save(editbuf *eb, char *fname, Int first, Int last, int append, io *iobuf) { char buf[BUF_SIZE]; struct stat sbuf; if (path_ed_write(filename, fname) == (char *) NULL || (P_stat(filename, &sbuf) >= 0 && (sbuf.st_mode & S_IFMT) != S_IFREG)) { return FALSE; } /* create file */ ffd = P_open(filename, (append) ? O_CREAT | O_APPEND | O_WRONLY | O_BINARY : O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0664); if (ffd < 0) { return FALSE; } /* initialize buffer */ buffer = buf; inbuf = 0; /* initialize statistics */ iostat = iobuf; iostat->lines = 0; iostat->chars = 0; iostat->zero = 0; iostat->split = 0; iostat->ill = FALSE; /* write range */ if (ec_push((ec_ftn) NULL)) { P_close(ffd); error((char *) NULL); /* pass on error */ } eb_range(eb, first, last, put_line, FALSE); if (P_write(ffd, buffer, inbuf) != inbuf) { error("error while writing file \"/%s\"", filename); } ec_pop(); P_close(ffd); return TRUE; }
/* * NAME: io_load() * DESCRIPTION: append block read from file after a line */ bool io_load(editbuf *eb, char *fname, Int l, io *iobuf) { char b[MAX_LINE_SIZE], buf[BUF_SIZE]; struct stat sbuf; /* open file */ if (path_ed_read(filename, fname) == (char *) NULL || P_stat(filename, &sbuf) < 0 || (sbuf.st_mode & S_IFMT) != S_IFREG) { return FALSE; } ffd = P_open(filename, O_RDONLY | O_BINARY, 0); if (ffd < 0) { return FALSE; } /* initialize buffers */ buffer = buf; inbuf = 0; lbuf = b; lbuflast = &b[MAX_LINE_SIZE - 1]; /* initialize statistics */ iostat = iobuf; iostat->lines = 0; iostat->chars = 0; iostat->zero = 0; iostat->split = 0; iostat->ill = FALSE; /* add the block to the edit buffer */ if (ec_push((ec_ftn) NULL)) { P_close(ffd); error((char *) NULL); /* pass on error */ } eb_add(eb, l, get_line); ec_pop(); P_close(ffd); return TRUE; }
// initialize: perform initialization tasks on a platform-specific level bool dynamic_linking::initialize() { // First, initialize all platform-specific stuff r_debug_addr = 0; r_state = 0; // First, find if we're a dynamic executable pdstring dyn_str = pdstring("DYNAMIC"); Symbol dyn_sym; if( ! proc->getSymbolInfo(dyn_str, dyn_sym)) { bperr( "Failed to find string DYNAMIC\n"); return false; } // step 2: find the base address and file descriptor of ld.so.1 // Three-step process. // 1) Examine aux vector for address of the loader Address ld_base = 0; dyn_lwp *replwp = proc->getRepresentativeLWP(); if(!(this->get_ld_base_addr(ld_base, replwp->auxv_fd()))) { return false; } // 2) Examine virtual address map for the name of the object (inode style) char ld_name[128+PRMAPSZ]; if(!(this->get_ld_name(ld_name, ld_base, replwp->map_fd(), proc->getPid()))) { return false; } // 3) Open that file int ld_fd = -1; ld_fd = open(ld_name, O_RDONLY, 0); if(ld_fd == -1) { perror("LD.SO"); return false; } // step 3: get its symbol table and find r_debug if (!(this->find_r_debug(ld_fd,ld_base))) { return false; } if (!(this->find_dlopen(ld_fd,ld_base))) { bperr( "WARNING: we didn't find dlopen in ld.so.1\n"); } P_close(ld_fd); dynlinked = true; return true; }
bool saveSharedLibrary::readNewLib(){ Elf32_Shdr *newsh, *shdr; Elf_Scn *scn, *newScn; Elf32_Ehdr *ehdr; Elf32_Phdr *oldPhdr; Elf_Data *strdata, *newdata, *olddata; if ((ehdr = elf32_getehdr(newElf)) == NULL){ fprintf(stderr," FAILED obtaining ehdr readNewLib\n"); return false; } if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){ if((strdata = elf_getdata(scn, NULL)) == NULL){ fprintf(stderr," Failed obtaining .shstrtab data buffer \n"); return false; } }else{ fprintf(stderr," FAILED obtaining .shstrtab scn\n"); } unsigned int newScnName =0; scn = NULL; Elf_Data shstrtabData; #if defined(i386_unknown_linux2_0) \ || defined(x86_64_unknown_linux2_4) /* save the PHDR from the library */ oldPhdr = elf32_getphdr(newElf); Elf32_Phdr phdrBuffer[ehdr->e_phnum]; /* copy it over to a buffer because, on linux, we will close newElf and reopen it. This closing of newElf should dealloc the data pointed to by oldPhdr */ memcpy(phdrBuffer, oldPhdr, ehdr->e_phnum * ehdr->e_phentsize); #endif for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) { //copy sections from newElf to newElf. shdr = elf32_getshdr(scn); olddata = elf_getdata(scn,NULL); if(!strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){ textAddr = shdr->sh_addr; textData = olddata; textSize = shdr->sh_size; } if(!strcmp( (char*) strdata->d_buf + shdr->sh_name, ".shstrtab")){ const char *secname =".dyninst_mutated\0"; shstrtabData.d_size = olddata->d_size+strlen(secname)+1; newShstrtabData_d_buf = new char[shstrtabData.d_size]; shstrtabData.d_buf = newShstrtabData_d_buf; memcpy( shstrtabData.d_buf, olddata->d_buf, olddata->d_size); memcpy(&(((char*) shstrtabData.d_buf)[olddata->d_size]), secname, strlen(secname)+1); newScnName = olddata->d_size; olddata->d_buf = shstrtabData.d_buf; olddata->d_size = shstrtabData.d_size; shdr->sh_size +=strlen(secname)+1; /* if the section header table is past this section in the ELF file, calculate the new offset*/ if(ehdr ->e_shoff > shdr->sh_offset){ ehdr->e_shoff += strlen(secname)+1; } elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY); } } ehdr-> e_shnum++; newScn = elf_newscn(newElf); newsh = elf32_getshdr(newScn); newsh->sh_name = newScnName; newsh->sh_type = SHT_NOBITS; // SHT_NOTE; newsh->sh_flags=0; newsh->sh_addr = 0x0; newsh->sh_offset = shdr->sh_offset; newsh->sh_size=0; newsh->sh_link=0; newsh->sh_info=0; newsh->sh_addralign = 0x1; //Values 0 and 1 mean the section has no alignment constraints. newsh->sh_entsize = 0; newdata = elf_newdata(newScn); newdata->d_size =0; newdata->d_buf=0; elf_update(newElf, ELF_C_NULL); /* elfutils on linux does not write data back to an ELF file you have opened correctly. Specifically, if you add a section the section's section header has space allocated for it in the file but no data is written to it. lovely, eh? to combat this, we reopen the file we just closed, and find the empty section header and fill it with data. */ #if defined(i386_unknown_linux2_0) \ || defined(x86_64_unknown_linux2_4) elf_update(newElf, ELF_C_WRITE); elf_end(newElf); P_close(newfd); if((newfd = (open(newpathname, O_RDWR)))==-1){ fprintf(stderr,"%s[%d]: cannot open new SO : %s\n",FILE__, __LINE__, newpathname); perror(" FAIL "); return false;; } if((newElf = elf_begin(newfd, ELF_C_RDWR, NULL)) ==NULL){ fprintf(stderr,"cannot open ELF %s \n", newpathname); return false;; } if ((ehdr = elf32_getehdr(newElf)) == NULL){ fprintf(stderr," FAILED obtaining ehdr readNewLib\n"); return false; } if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){ if((strdata = elf_getdata(scn, NULL)) == NULL){ fprintf(stderr," Failed obtaining .shstrtab data buffer \n"); return false; } }else{ fprintf(stderr," FAILED obtaining .shstrtab scn\n"); } scn = NULL; bool foundText=false; for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) { //copy sections from newElf to newElf. shdr = elf32_getshdr(scn); olddata = elf_getdata(scn,NULL); if(!foundText && !strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){ textAddr = shdr->sh_addr; textData = olddata; textSize = shdr->sh_size; elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY); foundText = true; } } /**UPDATE THE LAST SHDR **/ memset(shdr,'\0', sizeof(Elf32_Shdr)); shdr->sh_name = newScnName; shdr->sh_addr = 0x0; shdr->sh_type = 7; /* update the PHDR, well just make sure it is reset to what was in the original library */ Elf32_Phdr *newPhdr = elf32_getphdr(newElf); memcpy(newPhdr,phdrBuffer, ehdr->e_phnum * ehdr->e_phentsize); /* be extra sure, set the DIRTY flag */ elf_flagphdr(newElf, ELF_C_SET,ELF_F_DIRTY); elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY); elf_update(newElf, ELF_C_NULL); #endif return true; }
P_NOGEN int main(int argc, char** argv) { int err, i; P_t* pads; RMM_t* rmm_z; RMM_t* rmm_nz; RMM_t* mgr; RBuf_t* rbuf1; RBuf_t* rbuf2; void* buf1; void* buf2; void* buf2b; Pint32* ar1; Pint8* ar2; if (P_ERR == P_libopen(&pads, 0, 0, 1)) { error(2, "*** P_libopen failed ***"); exit(-1); } rmm_z = P_rmm_zero(pads); rmm_nz = P_rmm_nozero(pads); if (!(rbuf1 = RMM_new_rbuf(rmm_z))) { error(2, "*** RMM_new_rbuf on rmm_z failed ***"); exit(-1); } if (!(rbuf2 = RMM_new_rbuf(rmm_nz))) { error(2, "*** RMM_new_rbuf on rmm_nz failed ***"); exit(-1); } if ((err = RBuf_RESERVE_HINT(rbuf1, buf1, Pint32, 5, 10))) { error(2, "*** rbuf1 reserve failed with err= %d ***", err); exit(-1); } ar1 = (Pint32*)buf1; if ((err = RBuf_RESERVE_HINT(rbuf2, buf2, Pint8, 5, 0))) { error(2, "*** rbuf2 reserve failed with err= %d ***", err); exit(-1); } ar2 = (Pint8*)buf2; error(0, "Walking zerod data array"); for (i = 0; i < 5; i++) { error(0, "ar1[%d] = %d", i, ar1[i]); } error(0, "Walking non-zerod data array"); for (i = 0; i < 5; i++) { error(0, "ar2[%d] = %d", i, ar2[i]); } error(0, "Growing zerod array from 5 to 20 elts, one increment at a time"); for (i = 5; i < 20; i++) { if ((err = RBuf_RESERVE_HINT(rbuf1, buf1, Pint32, i+1, 10))) { error(2, "*** rbuf1 reserve failed with err= %d ***", err); exit(-1); } ar1 = (Pint32*)buf1; error(0, "ar1[%d] = %d", i, ar1[i]); } error(0, "Growing non-zerod array from 5 to 20 elts, one increment at a time"); for (i = 5; i < 20; i++) { if ((err = RBuf_RESERVE_HINT(rbuf2, buf2, Pint8, i+1, 0))) { error(2, "*** rbuf2 reserve failed with err= %d ***", err); exit(-1); } ar2 = (Pint8*)buf2; error(0, "ar2[%d] = %d", i, ar2[i]); } error(0, "Calling RMM_free_rbuf on rbuf1 (should cause 2 mem frees)"); err = RMM_free_rbuf(rbuf1); error(0, "=> RMM_rbuf_free on rbuf1 result: err= %d ***", err); error(0, "Calling RMM_free_rbuf on rbuf1 (should do nothing)"); err = RMM_free_rbuf(rbuf1); error(0, "=> RMM_rbuf_free on rbuf1 result: err= %d ***", err); error(0, "Calling RMM_free_rbuf_keep_buf on rbuf2 (should cause 1 mem free)"); err = RMM_free_rbuf_keep_buf(rbuf2, &buf2b, &mgr); error(0, "=> RMM_rbuf_free_keep_buf on rbuf2 result: err= %d ***", err); if (buf2b != buf2) { error(2, "*** unexpected: buf2b != buf2"); } if (mgr != rmm_nz) { error(2, "*** unexpected: mgr != rmm_nz"); } error(0, "Calling RMM_free_keep_buf on rbuf2 (should do nothing)"); err = RMM_free_rbuf_keep_buf(rbuf2, 0, 0); error(0, "=> RMM_rbuf_free_keep_buf on rbuf2 result: err= %d ***", err); error(0, "Calling RMM_free_buf on rbuf2's buffer (should cause 1 mem free)"); err = RMM_free_buf(mgr, buf2b); error(0, "=> RMM_free_buf on rbuf2's buffer result: err= %d ***", err); if (P_ERR == P_close(pads)) { error(2, "*** P_close failed ***"); exit(-1); } return 0; }
int main(int argc, char** argv) { P_t *pads; Pdisc_t my_disc = Pdefault_disc; Pio_disc_t *io_disc = 0; Ppos_t bpos, epos; PADS_TY( ) rep; PADS_TY(_pd) pd; PADS_TY(_m) m; #ifdef PADS_HDR_TY PADS_HDR_TY( ) hdr_rep; PADS_HDR_TY(_pd) hdr_pd; PADS_HDR_TY(_m) hdr_m; #endif /* PADS_HDR_TY */ Sfio_t *io; char *inName = 0; char *outName = 0; #ifdef E_REP_LEV my_disc.e_rep = E_REP_LEV; #endif #ifdef PRE_LIT_LWS my_disc.pre_lit_lws = PRE_LIT_LWS; #endif #ifdef WSPACE_OK my_disc.flags |= (Pflags_t)P_WSPACE_OK; #endif #ifdef COPY_STRINGS my_disc.copy_strings = 1; #endif #ifdef IN_TIME_ZONE my_disc.in_time_zone = IN_TIME_ZONE; error(0, "Note: set my_disc.in_time_zone to \"%s\"\n", IN_TIME_ZONE); #endif #ifdef OUT_TIME_ZONE my_disc.out_time_zone = OUT_TIME_ZONE; error(0, "Note: set my_disc.out_time_zone to \"%s\"\n", OUT_TIME_ZONE); #endif #ifdef TIMESTAMP_IN_FMT my_disc.in_formats.timestamp = TIMESTAMP_IN_FMT; #endif #ifdef DATE_IN_FMT my_disc.in_formats.date = DATE_IN_FMT; #endif #ifdef TIME_IN_FMT my_disc.in_formats.time = TIME_IN_FMT; #endif #ifdef TIMESTAMP_EXPLICIT_OUT_FMT my_disc.out_formats.timestamp_explicit = TIMESTAMP_EXPLICIT_OUT_FMT; #endif #ifdef TIMESTAMP_OUT_FMT my_disc.out_formats.timestamp = TIMESTAMP_OUT_FMT; #endif #ifdef DATE_EXPLICIT_OUT_FMT my_disc.out_formats.date_explicit = DATE_EXPLICIT_OUT_FMT; #endif #ifdef DATE_OUT_FMT my_disc.out_formats.date = DATE_OUT_FMT; #endif #ifdef TIME_EXPLICIT_OUT_FMT my_disc.out_formats.time_explicit = TIME_EXPLICIT_OUT_FMT; #endif #ifdef TIME_OUT_FMT my_disc.out_formats.time = TIME_OUT_FMT; #endif #ifdef IO_DISC_MK if (!(io_disc = IO_DISC_MK)) { error(ERROR_FATAL, "IO discipline make call [ " PDCI_MacroArg2String(IO_DISC_MK) " ] failed"); } #ifdef IO_DISC_DESCR else { error(0, "Installed " IO_DISC_DESCR); } #endif #endif if (argc >= 2) { inName = argv[1]; } else { inName = DEF_INPUT_FILE; } error(0, "Input file = %s\n", inName); if (argc == 3) { outName = argv[2]; } else { outName = DEF_OUTPUT_FILE; } error(0, "Output file = %s\n", outName); if (P_ERR == P_open(&pads, &my_disc, io_disc)) { error(ERROR_FATAL, "*** P_open failed ***"); } if (P_ERR == P_io_fopen(pads, inName)) { error(ERROR_FATAL, "*** P_io_fopen failed ***"); } if (!(io = P_fopen(outName, "w"))) { P_SYSERR1(pads->disc, "Failed to open output file \"%s\" for writing", outName); } if (P_ERR == PADS_TY(_init)(pads, &rep)) { error(ERROR_FATAL, "*** representation initialization failed ***"); } if (P_ERR == PADS_TY(_pd_init)(pads, &pd)) { error(ERROR_FATAL, "*** parse description initialization failed ***"); } /* /\*** New rec. code ***\/ */ if (P_ERR == PADS_TY(_m_rec_init)(pads, &m, READ_MASK)) { error(ERROR_FATAL, "*** recursive mask initialization failed ***"); } if (m != m->branches.element.interior) { error(ERROR_FATAL, "*** recursive mask initialization did not operate correctly. ***"); } /* /\*** End new rec. code ***\/ */ #ifdef PADS_HDR_TY if (P_ERR == PADS_HDR_TY(_init)(pads, &hdr_rep)) { error(ERROR_FATAL, "*** header representation initialization failed ***"); } if (P_ERR == PADS_HDR_TY(_pd_init)(pads, &hdr_pd)) { error(ERROR_FATAL, "*** header parse description initialization failed ***"); } /* init mask -- must do this! */ PADS_HDR_TY(_m_init)(pads, &hdr_m, P_CheckAndSet); #endif /* PADS_HDR_TY */ #ifdef PADS_HDR_TY /* * Try to read header */ if (!P_io_at_eof(pads)) { if (P_OK != PADS_HDR_TY(_read)(pads, &hdr_m, &hdr_pd, &hdr_rep EXTRA_HDR_READ_ARGS )) { error(ERROR_FATAL, "header read returned error"); } else { error(2, "Note: header read returned OK"); if (P_ERR == PADS_HDR_TY(_write2io)(pads, io, &hdr_pd, &hdr_rep EXTRA_HDR_READ_ARGS )) { error(ERROR_FATAL, "*** IO error during header write"); } } } #endif /* PADS_HDR_TY */ /* * Try to read each line of data */ while (!P_io_at_eof(pads) && (MAX_RECS == 0 || num_recs++ < MAX_RECS)) { P_io_getPos(pads, &bpos, 0); if (P_OK != PADS_TY(_read)(pads, &m, &pd, &rep EXTRA_READ_ARGS )) { #ifdef EXTRA_BAD_READ_CODE EXTRA_BAD_READ_CODE; #else if (my_disc.e_rep > PerrorRep_Min) { error(2, "read returned error"); } #endif } else { if (PADS_TY(_verify)(&(rep))) { error(2, "read reported no errors and passed predicate test."); } else { error(2, "read reported no errors but failed predicate test."); } #ifdef EXTRA_GOOD_READ_CODE EXTRA_GOOD_READ_CODE; #endif } P_io_getPos(pads, &epos, 0); if (P_POS_EQ(bpos, epos)) { error(ERROR_FATAL, "*** read loop stuck: read call did not advance IO cursor"); } tree_write2io(pads,io,&pd,&rep); } if (P_ERR == P_io_close(pads)) { error(ERROR_FATAL, "*** P_io_close failed ***"); } if (P_ERR == PADS_TY(_cleanup)(pads, &rep)) { error(ERROR_FATAL, "** representation cleanup failed **"); } if (P_ERR == PADS_TY(_pd_cleanup)(pads, &pd)) { error(ERROR_FATAL, "** parse descriptor cleanup failed **"); } if (P_ERR == P_close(pads)) { error(ERROR_FATAL, "*** P_close failed ***"); } sfclose(io); return 0; }
P_NOGEN #include <stdio.h> /* Remove comments to see classic example of a case where mixing binary data and newlines can fail */ /* #define USE_NLREC */ int main(int argc, char** argv) { /* int ctr; */ /* size_t n; */ /* unsigned char c; */ char fname[1000]; char* h; int rev = 0; P_t* pads; Pio_disc_t* io_disc; Pint8 i1; Pint16 i2; Pint32 i4; Pint64 i8; Puint8 ui1; Puint16 ui2; Puint32 ui4; Puint64 ui8; Pbase_m m = P_CheckAndSet; Pbase_pd pd; Pdisc_t my_disc = Pdefault_disc; size_t bytes_skipped; unsigned long ultmp; #ifdef USE_NLREC error(0, "\nUsing PADSC IO discipline nlrec_noseek\n\n"); io_disc = P_nlrec_noseek_make(0); #else error(0, "\nUsing PADSC IO discipline norec\n\n"); io_disc = P_norec_make(0); #endif if (argc >= 2) { h = argv[1]; } else { h = getenv("AST_ARCH"); } if (argc >= 3 && strcmp(argv[2], "rev") == 0) { rev = 1; } sprintf(fname, "../../data/ex_data.libtest2.%s", h); error(0, "fname = %s rev = %d\n", fname, rev); if (P_ERR == P_libopen(&pads, &my_disc, io_disc, 1)) { error(2, "*** P_libopen failed ***"); exit(-1); } switch (pads->m_endian) { case PbigEndian: my_disc.d_endian = rev ? PlittleEndian : PbigEndian; break; case PlittleEndian: my_disc.d_endian = rev ? PbigEndian : PlittleEndian; break; } if (P_ERR == P_io_fopen(pads, fname)) { error(2, "*** P_io_fopen failed ***"); exit(-1); } while (1) { if (P_io_at_eof(pads)) { error(0, "Main program found eof"); break; } if (P_ERR == Pb_int8_read(pads, &m, &pd, &i1)) { goto check_newline; } else { error(0, "Read bint8 : %ld", (long)i1); } if (P_ERR == Pb_uint8_read(pads, &m, &pd, &ui1)) { goto check_newline; } else { error(0, "Read buint8 : %lu", ui1); } if (P_ERR == Pb_int16_read(pads, &m, &pd, &i2)) { goto check_newline; } else { error(0, "Read bint16 : %ld", (long)i2); } if (P_ERR == Pb_uint16_read(pads, &m, &pd, &ui2)) { goto check_newline; } else { error(0, "Read buint16 : %lu", (unsigned long)ui2); } if (P_ERR == Pb_int32_read(pads, &m, &pd, &i4)) { goto check_newline; } else { error(0, "Read bint32 : %ld", (long)i4); } if (P_ERR == Pb_uint32_read(pads, &m, &pd, &ui4)) { goto check_newline; } else { error(0, "Read buint32 : %lu", (unsigned long)ui4); } if (P_ERR == Pb_int64_read(pads, &m, &pd, &i8)) { goto check_newline; } else { error(0, "Read bint64 : %lld", i8); } if (P_ERR == Pb_uint64_read(pads, &m, &pd, &ui8)) { goto check_newline; } else { error(0, "Read buint64 : %llu", ui8); } check_newline: #ifdef USE_NLREC if (P_ERR == P_io_next_rec(pads, &bytes_skipped)) { error(2, "Could not find EOR (newline), ending program"); goto done; } #else if (P_ERR == Pa_char_lit_scan1(pads, '\n', 1, 0, &bytes_skipped)) { error(2, "Could not find newline, ending program"); break; } #endif ultmp = bytes_skipped; error(0, "bytes_skipped to find EOR/newline = %ld", ultmp); } #ifdef USE_NLREC done: #endif if (P_ERR == P_io_close(pads)) { error(2, "*** P_io_close failed ***"); exit(-1); } if (P_ERR == P_close(pads)) { error(2, "*** P_close failed ***"); exit(-1); } return 0; }
P_NOGEN #define NEXT_REC do {\ if (strncmp(argv[1], "norec", 5) == 0) { \ if (P_ERR == Pe_char_lit_scan1(pads, '\n', 1, 0, &bytes_skipped)) { \ error(2, "Could not find EOR (0xFF), ending program"); \ goto done; \ } \ } else { \ if (P_ERR == P_io_next_rec(pads, &bytes_skipped)) { \ error(2, "Could not find EOR (OxFF), ending program"); \ goto done; \ } \ } \ ultmp = bytes_skipped; \ error(0, "next_rec returned bytes_skipped = %ld", ultmp); \ } while (0) int main(int argc, char** argv) { P_t* pads; Pio_disc_t* io_disc; Pint8 i8; Pint16 i16; Pint32 i32; Pint64 i64; Puint8 u8; Puint16 u16; Puint32 u32; Puint64 u64; Pdisc_t my_disc = Pdefault_disc; Pbase_m m = P_CheckAndSet; Pbase_pd pd; size_t bytes_skipped; unsigned long ultmp; my_disc.flags |= (Pflags_t)P_WSPACE_OK; if (argc != 2) { goto usage; } if (strcmp(argv[1], "fwrec") == 0) { io_disc = P_fwrec_make(0, 20, 1); } else if (strcmp(argv[1], "ctrec") == 0) { io_disc = P_ctrec_make(0xFF, 0); } else if (strcmp(argv[1], "norec") == 0) { io_disc = P_norec_make(0); } else if (strcmp(argv[1], "fwrec_noseek") == 0) { io_disc = P_fwrec_noseek_make(0, 20, 1); } else if (strcmp(argv[1], "ctrec_noseek") == 0) { io_disc = P_ctrec_noseek_make(0xFF, 0); } else if (strcmp(argv[1], "norec_noseek") == 0) { io_disc = P_norec_noseek_make(0); } else { goto usage; } if (!io_disc) { error(ERROR_FATAL, "\nFailed to install IO discipline %s", argv[1]); } else { error(0, "\nInstalled IO discipline %s", argv[1]); } if (P_ERR == P_libopen(&pads, &my_disc, io_disc, 1)) { error(2, "*** P_libopen failed ***"); return -1; } if (P_ERR == P_io_fopen(pads, "../../data/ex_data.bcd_test")) { error(2, "*** P_io_fopen failed ***"); return -1; } if (P_OK == Pbcd_int8_read(pads, &m, &pd, &i8, 3)) { error(0, "Read bcd integer: %ld", (long)i8); if (i8 != 0) { error(0, "XXX failure: should be %ld XXX", (long)0); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int8_read(pads, &m, &pd, &i8, 3)) { error(0, "Read bcd integer: %ld", (long)i8); if (i8 != P_MIN_INT8) { error(0, "XXX failure: should be %ld XXX", (long)P_MIN_INT8); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int8_read(pads, &m, &pd, &i8, 3)) { error(0, "Read bcd integer: %ld", (long)i8); if (i8 != P_MAX_INT8) { error(0, "XXX failure: should be %ld XXX", (long)P_MAX_INT8); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_uint8_read(pads, &m, &pd, &u8, 3)) { error(0, "Read bcd integer: %lu", (unsigned long)u8); if (u8 != P_MAX_UINT8) { error(0, "XXX failure: should be %lu XXX", (unsigned long)P_MAX_UINT8); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int16_read(pads, &m, &pd, &i16, 5)) { error(0, "Read bcd integer: %ld", (long)i16); if (i16 != P_MIN_INT16) { error(0, "XXX failure: should be %ld XXX", (long)P_MIN_INT16); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int16_read(pads, &m, &pd, &i16, 5)) { error(0, "Read bcd integer: %ld", (long)i16); if (i16 != P_MAX_INT16) { error(0, "XXX failure: should be %ld XXX", (long)P_MAX_INT16); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_uint16_read(pads, &m, &pd, &u16, 5)) { error(0, "Read bcd integer: %lu", (unsigned long)u16); if (u16 != P_MAX_UINT16) { error(0, "XXX failure: should be %lu XXX", (unsigned long)P_MAX_UINT16); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int32_read(pads, &m, &pd, &i32, 11)) { error(0, "Read bcd integer: %ld", (long)i32); if (i32 != P_MIN_INT32) { error(0, "XXX failure: should be %ld XXX", (long)P_MIN_INT32); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int32_read(pads, &m, &pd, &i32, 10)) { error(0, "Read bcd integer: %ld", (long)i32); if (i32 != P_MAX_INT32) { error(0, "XXX failure: should be %ld XXX", (long)P_MAX_INT32); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_uint32_read(pads, &m, &pd, &u32, 10)) { error(0, "Read bcd integer: %lu", (unsigned long)u32); if (u32 != P_MAX_UINT32) { error(0, "XXX failure: should be %lu XXX", (unsigned long)P_MAX_UINT32); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int64_read(pads, &m, &pd, &i64, 19)) { error(0, "Read bcd integer: %lld", (long long)i64); if (i64 != P_MIN_INT64) { error(0, "XXX failure: should be %lld XXX", (long long)P_MIN_INT64); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_int64_read(pads, &m, &pd, &i64, 19)) { error(0, "Read bcd integer: %lld", (long long)i64); if (i64 != P_MAX_INT64) { error(0, "XXX failure: should be %lld XXX", (long long)P_MAX_INT64); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_uint64_read(pads, &m, &pd, &u64, 20)) { error(0, "Read bcd integer: %llu", (unsigned long long)u64); if (u64 != P_MAX_UINT64) { error(0, "XXX failure: should be %llu XXX", (unsigned long long)P_MAX_UINT64); return -1; } } else { return -1; } NEXT_REC; done: if (P_ERR == P_io_close(pads)) { error(2, "*** P_io_close failed ***"); return -1; } if (P_ERR == P_close(pads)) { error(2, "*** P_close failed ***"); return -1; } return 0; usage: error(2, "\nUsage: %s <io-disc-name>\n\n\twhere <io-disc-name> is one of: fwrec, ctrec, norec, fwrec_noseek, ctrec_noseek, norec_noseek\n", argv[0]); return -1; }
/* * spell() - check for potentially missspelled words and offer them for * correction */ int spell(int f, int n) { int status, next, ret; char ccb[NLINE], *sp, *fn, *lp, *wsp, c, spc[NLINE]; UCS *b; UCS wb[NLINE], cb[NLINE]; EML eml; setimark(0, 1); emlwrite(_("Checking spelling..."), NULL); /* greetings */ if(alt_speller) return(alt_editor(1, 0)); /* f == 1 means fork speller */ if((fn = writetmp(0, NULL)) == NULL){ emlwrite(_("Can't write temp file for spell checker"), NULL); return(-1); } if((sp = (char *)getenv("SPELL")) == NULL) sp = SPELLER; /* exists? */ ret = (strlen(sp) + 1); snprintf(spc, sizeof(spc), "%s", sp); for(lp = spc, ret = FIOERR; *lp; lp++){ if((wsp = strpbrk(lp, " \t")) != NULL){ c = *wsp; *wsp = '\0'; } if(strchr(lp, '/')){ ret = fexist(lp, "x", (off_t *)NULL); } else{ char *path, fname[MAXPATH+1]; if(!(path = getenv("PATH"))) path = ":/bin:/usr/bin"; ret = ~FIOSUC; while(ret != FIOSUC && *path && pathcat(fname, &path, lp)) ret = fexist(fname, "x", (off_t *)NULL); } if(wsp) *wsp = c; if(ret == FIOSUC) break; } if(ret != FIOSUC){ eml.s = sp; emlwrite(_("\007Spell-checking file \"%s\" not found"), &eml); return(-1); } snprintf(ccb, sizeof(ccb), "( %s ) < %s", sp, fn); if(P_open(ccb) != FIOSUC){ /* read output from command */ our_unlink(fn); emlwrite(_("Can't fork spell checker"), NULL); return(-1); } ret = 1; while(ffgetline(wb, NLINE, NULL, 0) == FIOSUC && ret){ if((b = ucs4_strchr(wb, (UCS) '\n')) != NULL) *b = '\0'; ucs4_strncpy(cb, wb, NLINE); cb[NLINE-1] = '\0'; gotobob(0, 1); status = TRUE; next = 1; while(status){ if(next++) if(movetoword(wb) != TRUE) break; update(); (*term.t_rev)(1); pputs(wb, 1); /* highlight word */ (*term.t_rev)(0); if(ucs4_strcmp(cb, wb)){ char prompt[2*NLINE + 32]; char *wbu, *cbu; wbu = ucs4_to_utf8_cpystr(wb); cbu = ucs4_to_utf8_cpystr(cb); snprintf(prompt, sizeof(prompt), _("Replace \"%s\" with \"%s\""), wbu, cbu); status=mlyesno_utf8(prompt, TRUE); if(wbu) fs_give((void **) &wbu); if(cbu) fs_give((void **) &cbu); } else{ UCS *p; p = utf8_to_ucs4_cpystr(_("Edit a replacement: ")); status=mlreplyd(p, cb, NLINE, QDEFLT, NULL); if(p) fs_give((void **) &p); } curwp->w_flag |= WFMOVE; /* put cursor back */ sgarbk = 0; /* fake no-keymenu-change! */ update(); pputs(wb, 0); /* un-highlight */ switch(status){ case TRUE: chword(wb, cb, 0); /* correct word */ case FALSE: update(); /* place cursor */ break; case ABORT: emlwrite(_("Spell Checking Cancelled"), NULL); ret = FALSE; status = FALSE; break; case HELPCH: if(Pmaster){ VARS_TO_SAVE *saved_state; saved_state = save_pico_state(); (*Pmaster->helper)(pinespellhelp, _("Help with Spelling Checker"), 1); if(saved_state){ restore_pico_state(saved_state); free_pico_state(saved_state); } } else pico_help(spellhelp, _("Help with Spelling Checker"), 1); case (CTRL|'L'): next = 0; /* don't get next word */ sgarbf = TRUE; /* repaint full screen */ update(); status = TRUE; continue; default: emlwrite("Huh?", NULL); /* shouldn't get here, but.. */ status = TRUE; sleep(1); break; } forwword(0, 1); /* goto next word */ } } P_close(); /* clean up */ our_unlink(fn); swapimark(0, 1); curwp->w_flag |= WFHARD|WFMODE; sgarbk = TRUE; if(ret) emlwrite(_("Done checking spelling"), NULL); return(ret); }
P_NOGEN #define NEXT_REC do {\ if (strncmp(argv1, "norec", 5) == 0) { \ if (P_ERR == Pe_char_lit_scan1(pads, '\n', 1, 0, &bytes_skipped)) { \ error(2, "Could not find EOR (0xFF), ending program"); \ goto done; \ } \ } else { \ if (P_ERR == P_io_next_rec(pads, &bytes_skipped)) { \ error(2, "Could not find EOR (OxFF), ending program"); \ goto done; \ } \ } \ ultmp = bytes_skipped; \ error(0, "next_rec returned bytes_skipped = %ld", ultmp); \ } while (0) int main(int argc, char** argv) { P_t* pads; Pio_disc_t* io_disc; Pfpoint8 f8; Pfpoint16 f16; Pfpoint32 f32; Pfpoint64 f64; Pufpoint8 uf8; Pufpoint16 uf16; Pufpoint32 uf32; Pufpoint64 uf64; Pdisc_t my_disc = Pdefault_disc; Pbase_m m = P_CheckAndSet; Pbase_pd pd; size_t bytes_skipped; unsigned long ultmp; const char *argv1; my_disc.flags |= (Pflags_t)P_WSPACE_OK; if ((argc != 1) && (argc != 2)) { goto usage; } if (argc == 1) { argv1 = "fwrec_noseek"; } else { argv1 = argv[1]; } if (strcmp(argv1, "fwrec") == 0) { io_disc = P_fwrec_make(0, 20, 1); } else if (strcmp(argv1, "ctrec") == 0) { io_disc = P_ctrec_make(0xFF, 0); } else if (strcmp(argv1, "norec") == 0) { io_disc = P_norec_make(0); } else if (strcmp(argv1, "fwrec_noseek") == 0) { io_disc = P_fwrec_noseek_make(0, 20, 1); } else if (strcmp(argv1, "ctrec_noseek") == 0) { io_disc = P_ctrec_noseek_make(0xFF, 0); } else if (strcmp(argv1, "norec_noseek") == 0) { io_disc = P_norec_noseek_make(0); } else { goto usage; } if (!io_disc) { error(ERROR_FATAL, "\nFailed to install IO discipline %s", argv1); } else { error(0, "\nInstalled IO discipline %s", argv1); } if (P_ERR == P_libopen(&pads, &my_disc, io_disc, 1)) { error(2, "*** P_libopen failed ***"); return -1; } if (P_ERR == P_io_fopen(pads, "../../data/ex_data.bcd_test")) { error(2, "*** P_io_fopen failed ***"); return -1; } if (P_OK == Pbcd_fpoint8_read(pads, &m, &pd, &f8, 3, 0)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f8.num, (unsigned long)f8.denom); if (f8.num != 0) { error(0, "XXX failure: should be %ld XXX", (long)0); return -1; } if (f8.denom != 1) { error(0, "XXX failure: denom should be 1 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint8_read(pads, &m, &pd, &f8, 3, 1)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f8.num, (unsigned long)f8.denom); if (f8.num != P_MIN_INT8) { error(0, "XXX failure: should be %ld XXX", (long)P_MIN_INT8); return -1; } if (f8.denom != 10) { error(0, "XXX failure: denom should be 10 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint8_read(pads, &m, &pd, &f8, 3, 2)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f8.num, (unsigned long)f8.denom); if (f8.num != P_MAX_INT8) { error(0, "XXX failure: should be %ld XXX", (long)P_MAX_INT8); return -1; } if (f8.denom != 100) { error(0, "XXX failure: denom should be 100 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_ufpoint8_read(pads, &m, &pd, &uf8, 3, 2)) { error(0, "Read bcd ufpoint: num %lu denom %lu", (unsigned long)uf8.num, (unsigned long)uf8.denom); if (uf8.num != P_MAX_UINT8) { error(0, "XXX failure: should be %lu XXX", (unsigned long)P_MAX_UINT8); return -1; } if (uf8.denom != 100) { error(0, "XXX failure: denom should be 100 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint16_read(pads, &m, &pd, &f16, 5, 4)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f16.num, (unsigned long)f16.denom); if (f16.num != P_MIN_INT16) { error(0, "XXX failure: should be %ld XXX", (long)P_MIN_INT16); return -1; } if (f16.denom != 10000) { error(0, "XXX failure: denom should be 10,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint16_read(pads, &m, &pd, &f16, 5, 4)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f16.num, (unsigned long)f16.denom); if (f16.num != P_MAX_INT16) { error(0, "XXX failure: should be %ld XXX", (long)P_MAX_INT16); return -1; } if (f16.denom != 10000) { error(0, "XXX failure: denom should be 10,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_ufpoint16_read(pads, &m, &pd, &uf16, 5, 4)) { error(0, "Read bcd ufpoint: num %lu denom %lu", (unsigned long)uf16.num, (unsigned long)uf16.denom); if (uf16.num != P_MAX_UINT16) { error(0, "XXX failure: should be %lu XXX", (unsigned long)P_MAX_UINT16); return -1; } if (uf16.denom != 10000) { error(0, "XXX failure: denom should be 10,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint32_read(pads, &m, &pd, &f32, 11, 9)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f32.num, (unsigned long)f32.denom); if (f32.num != P_MIN_INT32) { error(0, "XXX failure: should be %ld XXX", (long)P_MIN_INT32); return -1; } if (f32.denom != 1000000000UL) { error(0, "XXX failure: denom should be 1,000,000,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint32_read(pads, &m, &pd, &f32, 10, 9)) { error(0, "Read bcd fpoint: num %ld denom %lu", (long)f32.num, (unsigned long)f32.denom); if (f32.num != P_MAX_INT32) { error(0, "XXX failure: should be %ld XXX", (long)P_MAX_INT32); return -1; } if (f32.denom != 1000000000UL) { error(0, "XXX failure: denom should be 1,000,000,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_ufpoint32_read(pads, &m, &pd, &uf32, 10, 9)) { error(0, "Read bcd ufpoint: num %lu denom %lu", (unsigned long)uf32.num, (unsigned long)uf32.denom); if (uf32.num != P_MAX_UINT32) { error(0, "XXX failure: should be %lu XXX", (unsigned long)P_MAX_UINT32); return -1; } if (uf32.denom != 1000000000UL) { error(0, "XXX failure: denom should be 1,000,000,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint64_read(pads, &m, &pd, &f64, 19, 19)) { error(0, "Read bcd fpoint: num %lld denom %llu", (long long)f64.num, (unsigned long long)f64.denom); if (f64.num != P_MIN_INT64) { error(0, "XXX failure: should be %lld XXX", (long long)P_MIN_INT64); return -1; } if (f64.denom != 10000000000000000000ULL) { error(0, "XXX failure: denom should be 10,000,000,000,000,000,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_fpoint64_read(pads, &m, &pd, &f64, 19, 19)) { error(0, "Read bcd fpoint: num %lld denom %llu", (long long)f64.num, (unsigned long long)f64.denom); if (f64.num != P_MAX_INT64) { error(0, "XXX failure: should be %lld XXX", (long long)P_MAX_INT64); return -1; } if (f64.denom != 10000000000000000000ULL) { error(0, "XXX failure: denom should be 10,000,000,000,000,000,000 XXX"); return -1; } } else { return -1; } NEXT_REC; if (P_OK == Pbcd_ufpoint64_read(pads, &m, &pd, &uf64, 20, 19)) { error(0, "Read bcd ufpoint: num %llu denom %llu", (unsigned long long)uf64.num, (unsigned long long)uf64.denom); if (uf64.num != P_MAX_UINT64) { error(0, "XXX failure: should be %llu XXX", (unsigned long long)P_MAX_UINT64); return -1; } if (uf64.denom != 10000000000000000000ULL) { error(0, "XXX failure: denom should be 10,000,000,000,000,000,000 XXX"); return -1; } } else { return -1; } NEXT_REC; done: if (P_ERR == P_io_close(pads)) { error(2, "*** P_io_close failed ***"); return -1; } if (P_ERR == P_close(pads)) { error(2, "*** P_close failed ***"); return -1; } return 0; usage: error(2, "\nUsage: %s [ <io-disc-name> ]\n\n\twhere <io-disc-name> is one of: fwrec, ctrec, norec, fwrec_noseek, ctrec_noseek, norec_noseek\n", argv[0]); return -1; }
rawTime64 pd_thread::getRawCpuTime_sw() { int status, fd; rawTime64 result = 0; int bufsize = 255; unsigned long utime, stime; char procfn[bufsize], *buf; cputime_access++; unsigned lwpId = dyninst_thread->getLWP(); if( use_task_stat == 0 ) { // Check if we should use /proc/*/task/*stat. status = snprintf( procfn, 254, "/proc/%d/task/%d/stat", lwpId, lwpId ); assert(! (status < 0 || status > 254)); fd = P_open( procfn, O_RDONLY, 0 ); if( fd < 0 ) { use_task_stat = -1; } else { P_close( fd ); use_task_stat = 1; } } if( use_task_stat == -1 ) { // /* DEBUG */ fprintf( stderr, "%s[%d]: using /proc/*/stat\n", __FILE__, __LINE__ ); status = snprintf( procfn, 254, "/proc/%d/stat", lwpId ); assert(! (status < 0 || status > 254)); } else if( use_task_stat == 1 ) { // /* DEBUG */ fprintf( stderr, "%s[%d]: using /proc/*/task/*/stat\n", __FILE__, __LINE__ ); status = snprintf( procfn, 254, "/proc/%d/task/%d/stat", lwpId, lwpId ); assert(! (status < 0 || status > 254)); } // The reason for this complicated method of reading and sseekf-ing is // to ensure that we read enough of the buffer 'atomically' to make sure // the data is consistent. Is this necessary? I *think* so. - nash do { fd = P_open(procfn, O_RDONLY, 0); if (fd < 0) { perror("getInferiorProcessCPUtime (open)"); return sw_previous_; } buf = new char[ bufsize ]; if ((int)P_read( fd, buf, bufsize ) < 0) { perror("getInferiorProcessCPUtime"); return sw_previous_; } /* While I'd bet that any of the numbers preceding utime and stime could overflow a signed int on IA-64, the compiler whines if you add length specifiers to elements whose conversion has been surpressed. */ if(2==sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu ", &utime, &stime ) ) { // These numbers are in 'jiffies' or timeslices. // Oh, and I'm also assuming that process time includes system time result = static_cast<rawTime64>(utime) + static_cast<rawTime64>(stime); break; } delete [] buf; bufsize = bufsize * 2; P_close( fd ); } while ( true ); delete [] buf; P_close(fd); if (result < sw_previous_) { pdlogLine("********* time going backwards in paradynd **********\n"); result = sw_previous_; } else sw_previous_ = result; return result; }
void mapped_module::parseFileLineInfo() { /* Determine if we've parsed this file already. */ image * moduleImage = obj()->parse_img(); assert( moduleImage != NULL ); const Object & moduleObject = moduleImage->getObject(); const char * fileName = moduleObject.getFileName(); /* We have not parsed this file already, so wind up libdwarf. */ int fd = open( fileName, O_RDONLY ); if (fd == -1) return; Dwarf_Debug dbg; int status = dwarf_init( fd, DW_DLC_READ, & pd_dwarf_handler, moduleObject.getErrFunc(), & dbg, NULL ); if( status != DW_DLV_OK ) { P_close( fd ); return; } /* Itereate over the CU headers. */ Dwarf_Unsigned header; while( dwarf_next_cu_header( dbg, NULL, NULL, NULL, NULL, & header, NULL ) == DW_DLV_OK ) { /* Acquire the CU DIE. */ Dwarf_Die cuDIE; status = dwarf_siblingof( dbg, NULL, & cuDIE, NULL); if( status != DW_DLV_OK ) { /* If we can get no (more) CUs, we're done. */ break; } /* Acquire this CU's source lines. */ Dwarf_Line * lineBuffer; Dwarf_Signed lineCount; status = dwarf_srclines( cuDIE, & lineBuffer, & lineCount, NULL ); /* See if we can get anything useful out of the next CU if this one is corrupt. */ if( status == DW_DLV_ERROR ) { dwarf_printf( "%s[%d]: dwarf_srclines() error.\n" ); } /* It's OK for a CU not to have line information. */ if( status != DW_DLV_OK ) { /* Free this CU's DIE. */ dwarf_dealloc( dbg, cuDIE, DW_DLA_DIE ); continue; } assert( status == DW_DLV_OK ); /* The 'lines' returned are actually interval markers; the code generated from lineNo runs from lineAddr up to but not including the lineAddr of the next line. */ bool isPreviousValid = false; Dwarf_Unsigned previousLineNo = 0; Dwarf_Addr previousLineAddr = 0x0; char * previousLineSource = NULL; Address baseAddr = obj()->codeBase(); /* Iterate over this CU's source lines. */ for( int i = 0; i < lineCount; i++ ) { /* Acquire the line number, address, source, and end of sequence flag. */ Dwarf_Unsigned lineNo; status = dwarf_lineno( lineBuffer[i], & lineNo, NULL ); if( status != DW_DLV_OK ) { continue; } Dwarf_Addr lineAddr; status = dwarf_lineaddr( lineBuffer[i], & lineAddr, NULL ); if( status != DW_DLV_OK ) { continue; } lineAddr += baseAddr; char * lineSource; status = dwarf_linesrc( lineBuffer[i], & lineSource, NULL ); if( status != DW_DLV_OK ) { continue; } Dwarf_Bool isEndOfSequence; status = dwarf_lineendsequence( lineBuffer[i], & isEndOfSequence, NULL ); if( status != DW_DLV_OK ) { continue; } if( isPreviousValid ) { /* If we're talking about the same (source file, line number) tuple, and it isn't the end of the sequence, we can coalesce the range. (The end of sequence marker marks discontinuities in the ranges.) */ if( lineNo == previousLineNo && strcmp( lineSource, previousLineSource ) == 0 && ! isEndOfSequence ) { /* Don't update the prev* values; just keep going until we hit the end of a sequence or a new sourcefile. */ continue; } /* end if we can coalesce this range */ /* Determine into which mapped_module this line information should be inserted. */ int_function * currentFunction = obj()->findFuncByAddr( previousLineAddr ); if( currentFunction == NULL ) { // /* DEBUG */ fprintf( stderr, "%s[%d]: failed to find function containing address 0x%lx; line number information will be lost.\n", __FILE__, __LINE__, lineAddr ); } else { mapped_module * currentModule = currentFunction->mod(); assert( currentModule != NULL ); char * canonicalLineSource = strrchr( previousLineSource, '/' ); if( canonicalLineSource == NULL ) { canonicalLineSource = previousLineSource; } else { ++canonicalLineSource; } /* The line 'canonicalLineSource:previousLineNo' has an address range of [previousLineAddr, lineAddr). */ currentModule->lineInfo_.addLine( canonicalLineSource, previousLineNo, previousLineAddr, lineAddr ); // /* DEBUG */ fprintf( stderr, "%s[%d]: inserted address range [0x%lx, 0x%lx) for source '%s:%u' into module '%s'.\n", __FILE__, __LINE__, previousLineAddr, lineAddr, canonicalLineSource, previousLineNo, currentModule->fileName().c_str() ); } /* end if we found the function by its address */ } /* end if the previous* variables are valid */ /* If the current line ends the sequence, invalidate previous; otherwise, update. */ if( isEndOfSequence ) { dwarf_dealloc( dbg, lineSource, DW_DLA_STRING ); isPreviousValid = false; } else { if( isPreviousValid ) { dwarf_dealloc( dbg, previousLineSource, DW_DLA_STRING ); } previousLineNo = lineNo; previousLineSource = lineSource; previousLineAddr = lineAddr; isPreviousValid = true; } /* end if line was not the end of a sequence */ } /* end iteration over source line entries. */ /* Free this CU's source lines. */ for( int i = 0; i < lineCount; i++ ) { dwarf_dealloc( dbg, lineBuffer[i], DW_DLA_LINE ); } dwarf_dealloc( dbg, lineBuffer, DW_DLA_LIST ); /* Free this CU's DIE. */ dwarf_dealloc( dbg, cuDIE, DW_DLA_DIE ); } /* end CU header iteration */ /* Wind down libdwarf. */ status = dwarf_finish( dbg, NULL ); if( status != DW_DLV_OK ) { dwarf_printf( "%s[%d]: failed to dwarf_finish()\n" ); } P_close( fd ); /* Note that we've parsed this file. */ } /* end parseFileLineInfo() */