Exemple #1
0
static int show_map(int pid)
{
    mapinfo *milist;
    mapinfo *mi;
    unsigned shared_dirty = 0;
    unsigned shared_clean = 0;
    unsigned private_dirty = 0;
    unsigned private_clean = 0;
    unsigned swap = 0;
    unsigned rss = 0;
    unsigned pss = 0;
    unsigned size = 0;
    unsigned count = 0;

    milist = load_maps(pid, addresses, !verbose && !addresses);
    if (milist == NULL) {
        return 1;
    }

    print_header();
    print_divider();

    for (mi = milist; mi;) {
        mapinfo* last = mi;

        shared_clean += mi->shared_clean;
        shared_dirty += mi->shared_dirty;
        private_clean += mi->private_clean;
        private_dirty += mi->private_dirty;
        swap += mi->swap;
        rss += mi->rss;
        pss += mi->pss;
        size += mi->size;
        count += mi->count;
        
        if (terse && !mi->private_dirty) {
            goto out;
        }

        if (addresses) {
            printf("%08x %08x ", mi->start, mi->end);
        }
        printf("%8d %8d %8d %8d %8d %8d %8d %8d", mi->size,
               mi->rss,
               mi->pss,
               mi->shared_clean, mi->shared_dirty,
               mi->private_clean, mi->private_dirty, mi->swap);
        if (!verbose && !addresses) {
            printf("%4d ", mi->count);
        }
        printf("%s%s\n", mi->name, mi->is_bss ? " [bss]" : "");

out:
        mi = mi->next;
        free(last);
    }

    print_divider();
    print_header();
    print_divider();

    if (addresses) {
        printf("                  ");
    }
    printf("%8d %8d %8d %8d %8d %8d %8d %8d", size,
            rss, pss,
            shared_clean, shared_dirty,
            private_clean, private_dirty, swap);
    if (!verbose && !addresses) {
        printf("%4d ", count);
    }
    printf("TOTAL\n");

    return 0;
}
Exemple #2
0
int load_bpf_file(char *path)
{
	int fd, i;
	Elf *elf;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr, shdr_prog;
	Elf_Data *data, *data_prog, *symbols = NULL;
	char *shname, *shname_prog;

	if (elf_version(EV_CURRENT) == EV_NONE)
		return 1;

	fd = open(path, O_RDONLY, 0);
	if (fd < 0)
		return 1;

	elf = elf_begin(fd, ELF_C_READ, NULL);

	if (!elf)
		return 1;

	if (gelf_getehdr(elf, &ehdr) != &ehdr)
		return 1;

	/* clear all kprobes */
	i = system("echo \"\" > /sys/kernel/debug/tracing/kprobe_events");

	/* scan over all elf sections to get license and map info */
	for (i = 1; i < ehdr.e_shnum; i++) {

		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
			continue;

		if (0) /* helpful for llvm debugging */
			printf("section %d:%s data %p size %zd link %d flags %d\n",
			       i, shname, data->d_buf, data->d_size,
			       shdr.sh_link, (int) shdr.sh_flags);

		if (strcmp(shname, "license") == 0) {
			processed_sec[i] = true;
			memcpy(license, data->d_buf, data->d_size);
		} else if (strcmp(shname, "version") == 0) {
			processed_sec[i] = true;
			if (data->d_size != sizeof(int)) {
				printf("invalid size of version section %zd\n",
				       data->d_size);
				return 1;
			}
			memcpy(&kern_version, data->d_buf, sizeof(int));
		} else if (strcmp(shname, "maps") == 0) {
			processed_sec[i] = true;
			if (load_maps(data->d_buf, data->d_size))
				return 1;
		} else if (shdr.sh_type == SHT_SYMTAB) {
			symbols = data;
		}
	}

	/* load programs that need map fixup (relocations) */
	for (i = 1; i < ehdr.e_shnum; i++) {

		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
			continue;
		if (shdr.sh_type == SHT_REL) {
			struct bpf_insn *insns;

			if (get_sec(elf, shdr.sh_info, &ehdr, &shname_prog,
				    &shdr_prog, &data_prog))
				continue;

			if (shdr_prog.sh_type != SHT_PROGBITS ||
			    !(shdr_prog.sh_flags & SHF_EXECINSTR))
				continue;

			insns = (struct bpf_insn *) data_prog->d_buf;

			processed_sec[shdr.sh_info] = true;
			processed_sec[i] = true;

			if (parse_relo_and_apply(data, symbols, &shdr, insns))
				continue;

			if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
			    memcmp(shname_prog, "kretprobe/", 10) == 0 ||
			    memcmp(shname_prog, "tracepoint/", 11) == 0 ||
			    memcmp(shname_prog, "xdp", 3) == 0 ||
			    memcmp(shname_prog, "perf_event", 10) == 0 ||
			    memcmp(shname_prog, "socket", 6) == 0 ||
			    memcmp(shname_prog, "cgroup/", 7) == 0)
				load_and_attach(shname_prog, insns, data_prog->d_size);
		}
	}

	/* load programs that don't use maps */
	for (i = 1; i < ehdr.e_shnum; i++) {

		if (processed_sec[i])
			continue;

		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
			continue;

		if (memcmp(shname, "kprobe/", 7) == 0 ||
		    memcmp(shname, "kretprobe/", 10) == 0 ||
		    memcmp(shname, "tracepoint/", 11) == 0 ||
		    memcmp(shname, "xdp", 3) == 0 ||
		    memcmp(shname, "perf_event", 10) == 0 ||
		    memcmp(shname, "socket", 6) == 0 ||
		    memcmp(shname, "cgroup/", 7) == 0)
			load_and_attach(shname, data->d_buf, data->d_size);
	}

	close(fd);
	return 0;
}
int show_map(int pid)
{
    mapinfo *milist;
    mapinfo *mi;
    unsigned shared_dirty = 0;
    unsigned shared_clean = 0;
    unsigned private_dirty = 0;
    unsigned private_clean = 0;
    unsigned rss = 0;
    unsigned pss = 0;
    unsigned size = 0;
    
    milist = load_maps(pid, verbose);
    if(milist == 0) {
        fprintf(stderr,"cannot get /proc/smaps for pid %d\n", pid);
        return 1;
    }

    if(addresses) {
        printf("start    end      shared   private  object\n");
        printf("-------- -------- -------- -------- ------------------------------\n");
    } else {
        printf("virtual                    shared   shared   private  private\n");
        printf("size     RSS      PSS      clean    dirty    clean    dirty    object\n");
        printf("-------- -------- -------- -------- -------- -------- -------- ------------------------------\n");
    }
    for(mi = milist; mi; mi = mi->next){
        shared_clean += mi->shared_clean;
        shared_dirty += mi->shared_dirty;
        private_clean += mi->private_clean;
        private_dirty += mi->private_dirty;
        rss += mi->rss;
        pss += mi->pss;
        size += mi->size;
        
        if(terse && !mi->private_dirty) continue;

        if(addresses) {
            printf("%08x %08x %8d %8d %s\n", mi->start, mi->end,
                   mi->shared_clean + mi->shared_dirty,
                   mi->private_clean + mi->private_dirty,
                   mi->name);
        } else {
            printf("%8d %8d %8d %8d %8d %8d %8d %s\n", mi->size,
                   mi->rss,
                   mi->pss,
                   mi->shared_clean, mi->shared_dirty,
                   mi->private_clean, mi->private_dirty,
                   mi->name);
        }
    }
    if(addresses) {
        printf("-------- -------- -------- -------- ------------------------------\n");
        printf("                  %8d %8d TOTAL\n", 
               shared_dirty + shared_clean, 
               private_dirty + private_clean);
    } else {
        printf("-------- -------- -------- -------- -------- -------- -------- ------------------------------\n");
        printf("%8d %8d %8d %8d %8d %8d %8d TOTAL\n", size,
               rss, pss,
               shared_clean, shared_dirty,
               private_clean, private_dirty);
    }
    return 0;
}