static void show_stat(struct stat64 *sp, const char *what) { if (strcmp(what, "mode") == 0) printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS)); else if (strcmp(what, "inode") == 0) printf("%lld", (long long)sp->st_ino); else if (strcmp(what, "nlink") == 0) printf("%lld", (long long)sp->st_nlink); else if (strcmp(what, "uid") == 0) printf("%d", (int)sp->st_uid); else if (strcmp(what, "gid") == 0) printf("%d", (int)sp->st_gid); else if (strcmp(what, "size") == 0) printf("%lld", (long long)sp->st_size); else if (strcmp(what, "blocks") == 0) printf("%lld", (long long)sp->st_blocks); else if (strcmp(what, "atime") == 0) printf("%lld", (long long)sp->st_atime); else if (strcmp(what, "mtime") == 0) printf("%lld", (long long)sp->st_mtime); else if (strcmp(what, "ctime") == 0) printf("%lld", (long long)sp->st_ctime); #ifdef HAS_CHFLAGS else if (strcmp(what, "flags") == 0) printf("%s", flags2str(chflags_flags, sp->st_flags)); #endif else if (strcmp(what, "type") == 0) { switch (sp->st_mode & S_IFMT) { case S_IFIFO: printf("fifo"); break; case S_IFCHR: printf("char"); break; case S_IFDIR: printf("dir"); break; case S_IFBLK: printf("block"); break; case S_IFREG: printf("regular"); break; case S_IFLNK: printf("symlink"); break; case S_IFSOCK: printf("socket"); break; default: printf("unknown"); break; } } else { printf("unknown"); } }
void decode_tcp(void *packet_data, int hdr_len) { struct tcphdr *tcp = (struct tcphdr *)packet_data; printf("Src port:%hu Dst port:%hu Seq:%u Ack:%u Off:%hhu %s\n", ntohs(tcp->th_sport), ntohs(tcp->th_dport), ntohl(tcp->th_seq), ntohl(tcp->th_ack), (unsigned char)tcp->th_off, flags2str(tcp->th_flags) ); printf("Win:%hu Sum:%hu Urg:%hu\n", ntohs(tcp->th_win), ntohs(tcp->th_sum), ntohs(tcp->th_urp)); if(hdr_len > 20) { unsigned char *opt = (unsigned char *)packet_data + 20; printf("Options: "); while( (*opt != 0) && ((unsigned int)opt - (unsigned int)packet_data < tcp->th_off*4) ) { unsigned char len = opt[1]; if(len == 0 && opt[0] != 1) { printf("0-length option(%u)\n", opt[0]); break; } len -= 2; switch(*opt) { case 1: printf("No-Op "); opt++; break; case 2: { unsigned short mss = 0; //assert(len == 2); if(len == 2) { mss = (opt[2] << 8) + (opt[3]); printf("MSS(%u) ", mss); } else { printf("MSS:l:%u ", len); } opt += opt[1]; break; } case 3: { unsigned char ws = 0; assert(len == 1); ws = opt[2]; printf("WS(%u) ", ws); opt += opt[1]; break; } case 4: { printf("SACK-Permitted "); opt += opt[1]; break; } case 5: { printf("SACK "); opt += opt[1]; break; } case 8: { int i; printf("Timestamp("); for(i = 0; i < len; i++) printf("%02x", opt[2+i]); printf(") "); opt += opt[1]; break; } default:{ printf("%u:%u ", opt[0], opt[1]); opt += opt[1]; break; } }; } printf("\n"); } }
static void rtnl_print_neigh(struct nlmsghdr *hdr) { struct ndmsg *ndm = NLMSG_DATA(hdr); uint32_t attrs_len = NDA_PAYLOAD(hdr); struct rtattr *attr = NDA_RTA(ndm); struct nda_cacheinfo *ci; int hz = get_user_hz(); char addr_str[256]; char hw_addr[30]; char states[256]; char flags[256]; if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ndm))) return; tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family, colorize_start(bold), addr_family2str(ndm->ndm_family), colorize_end()); tprintf(", Link Index %d", ndm->ndm_ifindex); tprintf(", State %d (%s%s%s)", ndm->ndm_state, colorize_start(bold), flags2str(neigh_states, ndm->ndm_state, states, sizeof(states)), colorize_end()); tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags, colorize_start(bold), flags2str(neigh_flags, ndm->ndm_flags, flags, sizeof(flags)), colorize_end()); tprintf(", Type %d (%s%s%s)", ndm->ndm_type, colorize_start(bold), route_type2str(ndm->ndm_type), colorize_end()); tprintf(" ]\n"); for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) { switch (attr->rta_type) { case NDA_DST: rta_fmt(attr, "Address %s", addr2str(ndm->ndm_family, RTA_DATA(attr), addr_str, sizeof(addr_str))); break; case NDA_LLADDR: rta_fmt(attr, "HW Address %s", device_addr2str(RTA_DATA(attr), RTA_LEN(attr), 0, hw_addr, sizeof(hw_addr))); break; case NDA_PROBES: rta_fmt(attr, "Probes %d", RTA_UINT32(attr)); break; case NDA_CACHEINFO: ci = RTA_DATA(attr); tprintf("\tA: Cache ("); tprintf("confirmed(%ds)", ci->ndm_confirmed / hz); tprintf(", used(%ds)", ci->ndm_used / hz); tprintf(", updated(%ds)", ci->ndm_updated / hz); tprintf(", refcnt(%d))", ci->ndm_refcnt); tprintf(", Len %d\n", RTA_LEN(attr)); break; default: rta_fmt(attr, "0x%x", attr->rta_type); break; } } }
static void rtnl_print_route(struct nlmsghdr *hdr) { struct rtmsg *rtm = NLMSG_DATA(hdr); uint32_t attrs_len = RTM_PAYLOAD(hdr); struct rtattr *attr = RTM_RTA(rtm); struct rta_cacheinfo *ci; int hz = get_user_hz(); char addr_str[256]; char flags[256]; if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*rtm))) return; tprintf(" [ Route Family %d (%s%s%s)", rtm->rtm_family, colorize_start(bold), addr_family2str(rtm->rtm_family), colorize_end()); tprintf(", Dst Len %d", rtm->rtm_dst_len); tprintf(", Src Len %d", rtm->rtm_src_len); tprintf(", ToS %d", rtm->rtm_tos); tprintf(", Table %d (%s%s%s)", rtm->rtm_table, colorize_start(bold), route_table2str(rtm->rtm_table), colorize_end()); tprintf(", Proto %d (%s%s%s)", rtm->rtm_protocol, colorize_start(bold), route_proto2str(rtm->rtm_protocol), colorize_end()); tprintf(", Scope %d (%s%s%s)", rtm->rtm_scope, colorize_start(bold), scope2str(rtm->rtm_scope), colorize_end()); tprintf(", Type %d (%s%s%s)", rtm->rtm_type, colorize_start(bold), route_type2str(rtm->rtm_type), colorize_end()); tprintf(", Flags 0x%x (%s%s%s) ]\n", rtm->rtm_flags, colorize_start(bold), flags2str(route_flags, rtm->rtm_flags, flags, sizeof(flags)), colorize_end()); for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) { switch (attr->rta_type) { case RTA_DST: rta_fmt(attr, "Dst %s", addr2str(rtm->rtm_family, RTA_DATA(attr), addr_str, sizeof(addr_str))); break; case RTA_SRC: rta_fmt(attr, "Src %s", addr2str(rtm->rtm_family, RTA_DATA(attr), addr_str, sizeof(addr_str))); break; case RTA_IIF: rta_fmt(attr, "Iif %d", RTA_INT(attr)); break; case RTA_OIF: rta_fmt(attr, "Oif %d", RTA_INT(attr)); break; case RTA_GATEWAY: rta_fmt(attr, "Gateway %s", addr2str(rtm->rtm_family, RTA_DATA(attr), addr_str, sizeof(addr_str))); break; case RTA_PRIORITY: rta_fmt(attr, "Priority %u", RTA_UINT32(attr)); break; case RTA_PREFSRC: rta_fmt(attr, "Pref Src %s", addr2str(rtm->rtm_family, RTA_DATA(attr), addr_str, sizeof(addr_str))); break; case RTA_MARK: rta_fmt(attr, "Mark 0x%x", RTA_UINT(attr)); break; case RTA_FLOW: rta_fmt(attr, "Flow 0x%x", RTA_UINT(attr)); break; case RTA_TABLE: rta_fmt(attr, "Table %d (%s%s%s)", RTA_UINT32(attr), colorize_start(bold), route_table2str(RTA_UINT32(attr)), colorize_end()); break; case RTA_CACHEINFO: ci = RTA_DATA(attr); tprintf("\tA: Cache ("); tprintf("expires(%ds)", ci->rta_expires / hz); tprintf(", error(%d)", ci->rta_error); tprintf(", users(%d)", ci->rta_clntref); tprintf(", used(%d)", ci->rta_used); tprintf(", last use(%ds)", ci->rta_lastuse / hz); tprintf(", id(%d)", ci->rta_id); tprintf(", ts(%d)", ci->rta_ts); tprintf(", ts age(%ds))", ci->rta_tsage); tprintf(", Len %d\n", RTA_LEN(attr)); break; default: rta_fmt(attr, "0x%x", attr->rta_type); break; } } }
/* load symbols out of FNAME */ void sym_loadsyms(char *fname, /* file name containing symbols */ int load_locals) /* load local symbols */ { int i, debug_cnt; #ifdef BFD_LOADER bfd *abfd; asymbol **syms; int storage, i, nsyms, debug_cnt; #else /* !BFD_LOADER */ int len; FILE *fobj; struct ecoff_filehdr fhdr; struct ecoff_aouthdr ahdr; struct ecoff_symhdr_t symhdr; char *strtab = NULL; struct ecoff_EXTR *extr; #endif /* BFD_LOADER */ if (syms_loaded) { /* symbols are already loaded */ /* FIXME: can't handle symbols from multiple files */ return; } #ifdef BFD_LOADER /* load the program into memory, try both endians */ if (!(abfd = bfd_openr(fname, "ss-coff-big"))) if (!(abfd = bfd_openr(fname, "ss-coff-little"))) fatal("cannot open executable `%s'", fname); /* this call is mainly for its side effect of reading in the sections. we follow the traditional behavior of `strings' in that we don't complain if we don't recognize a file to be an object file. */ if (!bfd_check_format(abfd, bfd_object)) { bfd_close(abfd); fatal("cannot open executable `%s'", fname); } /* sanity check, endian should be the same as loader.c encountered */ if (abfd->xvec->byteorder_big_p != (unsigned)ld_target_big_endian) panic("binary endian changed"); if ((bfd_get_file_flags(abfd) & (HAS_SYMS|HAS_LOCALS))) { /* file has locals, read them in */ storage = bfd_get_symtab_upper_bound(abfd); if (storage <= 0) fatal("HAS_SYMS is set, but `%s' still lacks symbols", fname); syms = (asymbol **)calloc(storage, 1); if (!syms) fatal("out of virtual memory"); nsyms = bfd_canonicalize_symtab (abfd, syms); if (nsyms <= 0) fatal("HAS_SYMS is set, but `%s' still lacks symbols", fname); /* * convert symbols to local format */ /* first count symbols */ sym_ndatasyms = 0; sym_ntextsyms = 0; for (i=0; i < nsyms; i++) { asymbol *sym = syms[i]; /* decode symbol type */ if (/* from the data section */ (!strcmp(sym->section->name, ".rdata") || !strcmp(sym->section->name, ".data") || !strcmp(sym->section->name, ".sdata") || !strcmp(sym->section->name, ".bss") || !strcmp(sym->section->name, ".sbss")) /* from a scope we are interested in */ && RELEVANT_SCOPE(sym)) { /* data segment symbol */ sym_ndatasyms++; #ifdef PRINT_SYMS fprintf(stderr, "+sym: %s sect: %s flags: %s value: 0x%08lx\n", sym->name, sym->section->name, flags2str(sym->flags), sym->value + sym->section->vma); #endif /* PRINT_SYMS */ } else if (/* from the text section */ !strcmp(sym->section->name, ".text") /* from a scope we are interested in */ && RELEVANT_SCOPE(sym)) { /* text segment symbol */ sym_ntextsyms++; #ifdef PRINT_SYMS fprintf(stderr, "+sym: %s sect: %s flags: %s value: 0x%08lx\n", sym->name, sym->section->name, flags2str(sym->flags), sym->value + sym->section->vma); #endif /* PRINT_SYMS */ } else { /* non-segment sections */ #ifdef PRINT_SYMS fprintf(stderr, "-sym: %s sect: %s flags: %s value: 0x%08lx\n", sym->name, sym->section->name, flags2str(sym->flags), sym->value + sym->section->vma); #endif /* PRINT_SYMS */ } } sym_nsyms = sym_ntextsyms + sym_ndatasyms; if (sym_nsyms <= 0) fatal("`%s' has no text or data symbols", fname); /* allocate symbol space */ sym_db = (struct sym_sym_t *)calloc(sym_nsyms, sizeof(struct sym_sym_t)); if (!sym_db) fatal("out of virtual memory"); /* convert symbols to internal format */ for (debug_cnt=0, i=0; i < nsyms; i++) { asymbol *sym = syms[i]; /* decode symbol type */ if (/* from the data section */ (!strcmp(sym->section->name, ".rdata") || !strcmp(sym->section->name, ".data") || !strcmp(sym->section->name, ".sdata") || !strcmp(sym->section->name, ".bss") || !strcmp(sym->section->name, ".sbss")) /* from a scope we are interested in */ && RELEVANT_SCOPE(sym)) { /* data segment symbol, insert into symbol database */ sym_db[debug_cnt].name = mystrdup((char *)sym->name); sym_db[debug_cnt].seg = ss_data; sym_db[debug_cnt].initialized = (!strcmp(sym->section->name, ".rdata") || !strcmp(sym->section->name, ".data") || !strcmp(sym->section->name, ".sdata")); sym_db[debug_cnt].pub = (sym->flags & BSF_GLOBAL); sym_db[debug_cnt].local = (sym->name[0] == '$'); sym_db[debug_cnt].addr = sym->value + sym->section->vma; debug_cnt++; } else if (/* from the text section */ !strcmp(sym->section->name, ".text") /* from a scope we are interested in */ && RELEVANT_SCOPE(sym)) { /* text segment symbol, insert into symbol database */ sym_db[debug_cnt].name = mystrdup((char *)sym->name); sym_db[debug_cnt].seg = ss_text; sym_db[debug_cnt].initialized = /* seems reasonable */TRUE; sym_db[debug_cnt].pub = (sym->flags & BSF_GLOBAL); sym_db[debug_cnt].local = (sym->name[0] == '$'); sym_db[debug_cnt].addr = sym->value + sym->section->vma; debug_cnt++; } else { /* non-segment sections */ } } /* sanity check */ if (debug_cnt != sym_nsyms) panic("could not locate all counted symbols"); /* release bfd symbol storage */ free(syms); } /* done with file, close if */ if (!bfd_close(abfd)) fatal("could not close executable `%s'", fname); #else /* !BFD_LOADER */ /* load the program into memory, try both endians */ #if defined(_MSC_VER) fobj = fopen(fname, "rb"); #else fobj = fopen(fname, "r"); #endif if (!fobj) fatal("cannot open executable `%s'", fname); if (fread(&fhdr, sizeof(struct ecoff_filehdr), 1, fobj) < 1) fatal("cannot read header from executable `%s'", fname); /* record endian of target */ if (fhdr.f_magic != ECOFF_ALPHAMAGIC) fatal("bad magic number in executable `%s'", fname); if (fread(&ahdr, sizeof(struct ecoff_aouthdr), 1, fobj) < 1) fatal("cannot read AOUT header from executable `%s'", fname); /* seek to the beginning of the symbolic header */ fseek(fobj, (long)fhdr.f_symptr, 0); if (fread(&symhdr, sizeof(struct ecoff_symhdr_t), 1, fobj) < 1) fatal("could not read symbolic header from executable `%s'", fname); if (symhdr.magic != ECOFF_magicSym) fatal("bad magic number (0x%x) in symbolic header", symhdr.magic); /* allocate space for the string table */ len = symhdr.issMax + symhdr.issExtMax; strtab = (char *)calloc(len, sizeof(char)); if (!strtab) fatal("out of virtual memory"); /* read all the symbol names into memory */ fseek(fobj, (long)symhdr.cbSsExtOffset /* cbSsOffset */, 0); if (fread(strtab, len, 1, fobj) < 0) fatal("error while reading symbol table names"); /* allocate symbol space */ len = symhdr.isymMax + symhdr.iextMax; if (len <= 0) fatal("`%s' has no text or data symbols", fname); sym_db = (struct sym_sym_t *)calloc(len, sizeof(struct sym_sym_t)); if (!sym_db) fatal("out of virtual memory"); /* allocate space for the external symbol entries */ extr = (struct ecoff_EXTR *)calloc(symhdr.iextMax, sizeof(struct ecoff_EXTR)); if (!extr) fatal("out of virtual memory"); fseek(fobj, (long)symhdr.cbExtOffset, 0); if (fread(extr, sizeof(struct ecoff_EXTR), symhdr.iextMax, fobj) < 0) fatal("error reading external symbol entries"); sym_nsyms = 0; sym_ndatasyms = 0; sym_ntextsyms = 0; /* convert symbols to internal format */ for (i=0; i < symhdr.iextMax; i++) { int str_offset; str_offset = symhdr.issMax + extr[i].asym.iss; #if 0 printf("ext %2d: ifd = %2d, iss = %3d, value = %8x, st = %3x, " "sc = %3x, index = %3x\n", i, extr[i].ifd, extr[i].asym.iss, extr[i].asym.value, extr[i].asym.st, extr[i].asym.sc, extr[i].asym.index); printf(" %08x %2d %2d %s\n", extr[i].asym.value, extr[i].asym.st, extr[i].asym.sc, &strtab[str_offset]); #endif switch (extr[i].asym.st) { case ECOFF_stGlobal: case ECOFF_stStatic: /* from data segment */ sym_db[sym_nsyms].name = mystrdup(&strtab[str_offset]); sym_db[sym_nsyms].seg = ss_data; sym_db[sym_nsyms].initialized = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].pub = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].local = /* FIXME: ??? */FALSE; sym_db[sym_nsyms].addr = extr[i].asym.value; sym_nsyms++; sym_ndatasyms++; break; case ECOFF_stProc: case ECOFF_stStaticProc: case ECOFF_stLabel: /* from text segment */ sym_db[sym_nsyms].name = mystrdup(&strtab[str_offset]); sym_db[sym_nsyms].seg = ss_text; sym_db[sym_nsyms].initialized = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].pub = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].local = /* FIXME: ??? */FALSE; sym_db[sym_nsyms].addr = extr[i].asym.value; sym_nsyms++; sym_ntextsyms++; break; default: /* FIXME: ignored... */; #if 0 fprintf(stderr, "** skipping: %s...\n", &strtab[str_offset]); break; #endif } } free(extr); /* done with the executable, close it */ if (fclose(fobj)) fatal("could not close executable `%s'", fname); #endif /* BFD_LOADER */ /* * generate various sortings */ /* all symbols sorted by address and name */ sym_syms = (struct sym_sym_t **)calloc(sym_nsyms, sizeof(struct sym_sym_t *)); if (!sym_syms) fatal("out of virtual memory"); sym_syms_by_name = (struct sym_sym_t **)calloc(sym_nsyms, sizeof(struct sym_sym_t *)); if (!sym_syms_by_name) fatal("out of virtual memory"); for (debug_cnt=0, i=0; i<sym_nsyms; i++) { sym_syms[debug_cnt] = &sym_db[i]; sym_syms_by_name[debug_cnt] = &sym_db[i]; debug_cnt++; } /* sanity check */ if (debug_cnt != sym_nsyms) panic("could not locate all symbols"); /* sort by address */ qsort(sym_syms, sym_nsyms, sizeof(struct sym_sym_t *), (void *)acmp); /* sort by name */ qsort(sym_syms_by_name, sym_nsyms, sizeof(struct sym_sym_t *), (void *)ncmp); /* text segment sorted by address and name */ sym_textsyms = (struct sym_sym_t **)calloc(sym_ntextsyms, sizeof(struct sym_sym_t *)); if (!sym_textsyms) fatal("out of virtual memory"); sym_textsyms_by_name = (struct sym_sym_t **)calloc(sym_ntextsyms, sizeof(struct sym_sym_t *)); if (!sym_textsyms_by_name) fatal("out of virtual memory"); for (debug_cnt=0, i=0; i<sym_nsyms; i++) { if (sym_db[i].seg == ss_text) { sym_textsyms[debug_cnt] = &sym_db[i]; sym_textsyms_by_name[debug_cnt] = &sym_db[i]; debug_cnt++; } } /* sanity check */ if (debug_cnt != sym_ntextsyms) panic("could not locate all text symbols"); /* sort by address */ qsort(sym_textsyms, sym_ntextsyms, sizeof(struct sym_sym_t *), (void *)acmp); /* sort by name */ qsort(sym_textsyms_by_name, sym_ntextsyms, sizeof(struct sym_sym_t *), (void *)ncmp); /* data segment sorted by address and name */ sym_datasyms = (struct sym_sym_t **)calloc(sym_ndatasyms, sizeof(struct sym_sym_t *)); if (!sym_datasyms) fatal("out of virtual memory"); sym_datasyms_by_name = (struct sym_sym_t **)calloc(sym_ndatasyms, sizeof(struct sym_sym_t *)); if (!sym_datasyms_by_name) fatal("out of virtual memory"); for (debug_cnt=0, i=0; i<sym_nsyms; i++) { if (sym_db[i].seg == ss_data) { sym_datasyms[debug_cnt] = &sym_db[i]; sym_datasyms_by_name[debug_cnt] = &sym_db[i]; debug_cnt++; } } /* sanity check */ if (debug_cnt != sym_ndatasyms) panic("could not locate all data symbols"); /* sort by address */ qsort(sym_datasyms, sym_ndatasyms, sizeof(struct sym_sym_t *), (void *)acmp); /* sort by name */ qsort(sym_datasyms_by_name, sym_ndatasyms, sizeof(struct sym_sym_t *), (void *)ncmp); /* compute symbol sizes */ for (i=0; i<sym_ntextsyms; i++) { sym_textsyms[i]->size = (i != (sym_ntextsyms - 1) ? (sym_textsyms[i+1]->addr - sym_textsyms[i]->addr) : ((ld_text_base + ld_text_size) - sym_textsyms[i]->addr)); } for (i=0; i<sym_ndatasyms; i++) { sym_datasyms[i]->size = (i != (sym_ndatasyms - 1) ? (sym_datasyms[i+1]->addr - sym_datasyms[i]->addr) : ((ld_data_base + ld_data_size) - sym_datasyms[i]->addr)); } /* symbols are now available for use */ syms_loaded = TRUE; }
static void pmaps(int pid, print_flags_t pflags, regex_t *regex, int fd_kflags, int fd_kcount) { FILE *maps = NULL; int fd_p=-1; unsigned long start_addr, end_addr; char *line=0; size_t line_n=0; maps = fopen(proc_fn(pid, "maps"), "r"); if (!maps) { fprintf(stderr, "ERROR: could not open /proc/%d/maps: %s\n", pid, strerror(errno)); goto done; } fd_p = open(proc_fn(pid, "pagemap"), O_RDONLY); if (fd_p<0) { fprintf(stderr, "ERROR: could not open /proc/%d/pagemap: %s\n", pid, strerror(errno)); goto done; } while (1) { int ret = getline(&line, &line_n, maps); if (ret == -1) { goto done; } if (pflags & STACK_ONLY) { if (strstr(line, "[stack]") == NULL) continue; } else if (pflags & HEAP_ONLY) { if (strstr(line, "[heap]") == NULL) continue; } else if (regex) { if (regexec(regex, line, 0, NULL, 0) != 0) continue; } if (sscanf(line, "%lx-%lx", &start_addr, &end_addr) != 2) { (void) fprintf(stderr, "ERROR: did not understand line from /proc/pid/maps. :(\n"); goto done; } (void) printf("%s", line); unsigned long page_start = start_addr / pagesize; unsigned long page_end = end_addr / pagesize; x_lseek(fd_p, sizeof(uint64_t)*page_start, SEEK_SET); unsigned long nr_read = 0; unsigned long nr_read_total = 0; for (; page_start < page_end; page_start += BSIZE, nr_read_total += nr_read) { nr_read = min_ul(page_end-page_start, BSIZE); if (read(fd_p, pagemap, nr_read*sizeof(uint64_t)) != (ssize_t)(nr_read*sizeof(uint64_t))) { // Reading the /proc/pid/pagemap entry for // /proc/pid/maps [vsyscall] resulted in zero // byte reads. Let's just ignore such cases. continue; } populate(fd_kflags, pageflags, nr_read); populate(fd_kcount, pagecount, nr_read); for (unsigned i=0; i < nr_read; ++i) { if (PMAP_PRESENT&pagemap[i] && !(pflags & SWAPPED_ONLY)) { printf(" %#lx -> pfn:%#08llx count:%4llu flags:%s\n", start_addr + (nr_read_total+i)*pagesize, PMAP_PFN&pagemap[i], (unsigned long long)pagecount[i], flags2str(pageflags[i])); } else if (PMAP_SWAPPED&pagemap[i] && !(pflags & RESIDENT_ONLY)) { printf(" #%#lx -> swaptype:%#llx swapoff:%#08llx\n", start_addr + (nr_read_total+i)*pagesize, PMAP_SWAP_TYPE&pagemap[i], (PMAP_SWAP_OFF&pagemap[i])>>5); } else if (!(pflags & (SWAPPED_ONLY|RESIDENT_ONLY))) { printf(" !%#lx\n", start_addr + (nr_read_total+i)*pagesize); } } }
static int look(char *arg) { struct ps_prochandle *Pr; int gcode; size_t sz; void *pdata; char *x; int i; boolean_t nodata; prpriv_t *ppriv; procname = arg; /* for perr() */ if ((Pr = proc_arg_grab(arg, set ? PR_ARG_PIDS : PR_ARG_ANY, PGRAB_RETAIN | PGRAB_FORCE | (set ? 0 : PGRAB_RDONLY) | PGRAB_NOSTOP, &gcode)) == NULL) { (void) fprintf(stderr, "%s: cannot examine %s: %s\n", command, arg, Pgrab_error(gcode)); return (1); } if (Ppriv(Pr, &ppriv) == -1) { perr(command); Prelease(Pr, 0); return (1); } sz = PRIV_PRPRIV_SIZE(ppriv); /* * The ppriv fields are unsigned and may overflow, so check them * separately. Size must be word aligned, so check that too. * Make sure size is "smallish" too. */ if ((sz & 3) || ppriv->pr_nsets == 0 || sz / ppriv->pr_nsets < ppriv->pr_setsize || ppriv->pr_infosize > sz || sz > 1024 * 1024) { (void) fprintf(stderr, "%s: %s: bad PRNOTES section, size = %lx\n", command, arg, (long)sz); Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (1); } if (set) { privupdate(ppriv, arg); if (Psetpriv(Pr, ppriv) != 0) { perr(command); Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (1); } Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (0); } if (Pstate(Pr) == PS_DEAD) { (void) printf("core '%s' of %d:\t%.70s\n", arg, (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs); pdata = Pprivinfo(Pr); nodata = Pstate(Pr) == PS_DEAD && pdata == NULL; } else { (void) printf("%d:\t%.70s\n", (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs); pdata = NULL; nodata = B_FALSE; } x = (char *)ppriv + sz - ppriv->pr_infosize; while (x < (char *)ppriv + sz) { /* LINTED: alignment */ priv_info_t *pi = (priv_info_t *)x; priv_info_uint_t *pii; switch (pi->priv_info_type) { case PRIV_INFO_FLAGS: /* LINTED: alignment */ pii = (priv_info_uint_t *)x; (void) printf("flags ="); flags2str(pii->val); (void) putchar('\n'); break; default: (void) fprintf(stderr, "%s: unknown priv_info: %d\n", arg, pi->priv_info_type); break; } if (pi->priv_info_size > ppriv->pr_infosize || pi->priv_info_size <= sizeof (priv_info_t) || (pi->priv_info_size & 3) != 0) { (void) fprintf(stderr, "%s: bad priv_info_size: %u\n", arg, pi->priv_info_size); break; } x += pi->priv_info_size; } for (i = 0; i < ppriv->pr_nsets; i++) { extern const char *__priv_getsetbynum(const void *, int); const char *setnm = pdata ? __priv_getsetbynum(pdata, i) : priv_getsetbynum(i); priv_chunk_t *pc = (priv_chunk_t *)&ppriv->pr_sets[ppriv->pr_setsize * i]; (void) printf("\t%c: ", setnm && !nodata ? *setnm : '?'); if (!nodata) { extern char *__priv_set_to_str(void *, const priv_set_t *, char, int); priv_set_t *pset = (priv_set_t *)pc; char *s; if (pdata) s = __priv_set_to_str(pdata, pset, ',', mode); else s = priv_set_to_str(pset, ',', mode); (void) puts(s); free(s); } else { int j; for (j = 0; j < ppriv->pr_setsize; j++) (void) printf("%08x", pc[j]); (void) putchar('\n'); } } Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (0); }