Пример #1
0
/*
 * This function is slow because it doesn't use the memory.
 * It is useful at few calls like get_str_osrelease_from_vmlinux().
 */
off_t
vaddr_to_offset_slow(int fd, char *filename, unsigned long long vaddr)
{
	off_t offset = 0;
	int i, phnum, flag_elf64, elf_format;
	unsigned int num_load;
	Elf64_Phdr load64;
	Elf32_Phdr load32;

	elf_format = check_elf_format(fd, filename, &phnum, &num_load);
	if (elf_format == ELF64)
		flag_elf64 = TRUE;
	else if (elf_format == ELF32)
		flag_elf64 = FALSE;
	else
		return 0;

	for (i = 0; i < phnum; i++) {
		if (flag_elf64) { /* ELF64 */
			if (!get_elf64_phdr(fd, filename, i, &load64)) {
				ERRMSG("Can't find Phdr %d.\n", i);
				return 0;
			}
			if (load64.p_type != PT_LOAD)
				continue;

			if ((vaddr < load64.p_vaddr)
			    || (load64.p_vaddr + load64.p_filesz <= vaddr))
				continue;

			offset = load64.p_offset + (vaddr - load64.p_vaddr);
			break;
		} else {         /* ELF32 */
			if (!get_elf32_phdr(fd, filename, i, &load32)) {
				ERRMSG("Can't find Phdr %d.\n", i);
				return 0;
			}
			if (load32.p_type != PT_LOAD)
				continue;

			if ((vaddr < load32.p_vaddr)
			    || (load32.p_vaddr + load32.p_filesz <= vaddr))
				continue;

			offset = load32.p_offset + (vaddr - load32.p_vaddr);
			break;
		}
	}
	return offset;
}
Пример #2
0
    /* Note, the `start_addr' should NOT be NULL! */
    BinParser* get_parser(const uint8_t* start_addr, uint64_t len)
    {
        assert(start_addr != NULL);

        bin_fmt_t bf = BF_UNKNOWN;

        bf = check_elf_format(start_addr, len);
        if (bf == BF_ELF64) return new Elf64Parser(start_addr, len);

        /* Doesn't matter whether it is an ELF32 shared library or not,
         * here we just make sure that the factory method won't return
         * NULL.
         */
        return new Elf32Parser(start_addr, len);
    }
Пример #3
0
/*
 * Get ELF information about /proc/vmcore.
 */
int
get_elf_info(int fd, char *filename)
{
	int i, j, phnum, elf_format;
	Elf64_Phdr phdr;

	/*
	 * Check ELF64 or ELF32.
	 */
	elf_format = check_elf_format(fd, filename, &phnum, &num_pt_loads);
	if (elf_format == ELF64)
		flags_memory |= MEMORY_ELF64;
	else if (elf_format != ELF32)
		return FALSE;

	if (!num_pt_loads) {
		ERRMSG("Can't get the number of PT_LOAD.\n");
		return FALSE;
	}

	/*
	 * The below file information will be used as /proc/vmcore.
	 */
	fd_memory   = fd;
	name_memory = filename;

	pt_loads = calloc(sizeof(struct pt_load_segment), num_pt_loads);
	if (pt_loads == NULL) {
		ERRMSG("Can't allocate memory for the PT_LOAD. %s\n",
		    strerror(errno));
		return FALSE;
	}
	for (i = 0, j = 0; i < phnum; i++) {
		if (!get_phdr_memory(i, &phdr))
			return FALSE;

		if (phdr.p_type == PT_NOTE) {
			set_pt_note(phdr.p_offset, phdr.p_filesz);
		}
		if (phdr.p_type != PT_LOAD)
			continue;

		if (j == 0) {
			offset_pt_load_memory = phdr.p_offset;
			if (offset_pt_load_memory == 0) {
				ERRMSG("Can't get the offset of page data.\n");
				return FALSE;
			}
		}
		if (j >= num_pt_loads)
			return FALSE;
		if(!dump_Elf_load(&phdr, j))
			return FALSE;
		j++;
	}
	max_file_offset = 0;
	for (i = 0; i < num_pt_loads; ++i) {
		struct pt_load_segment *p = &pt_loads[i];
		max_file_offset = MAX(max_file_offset,
				      p->file_offset + p->phys_end - p->phys_start);
	}
	if (!has_pt_note()) {
		ERRMSG("Can't find PT_NOTE Phdr.\n");
		return FALSE;
	}
	if (!get_pt_note_info()) {
		ERRMSG("Can't get PT_NOTE information.\n");
		return FALSE;
	}
	return TRUE;
}