struct ld_procmaps *ld_load_maps(pid_t pid, int verbose, size_t *num)
{
	char filename[OS_MAX_BUFFER];
	char appname[OS_MAX_BUFFER];
	FILE *ff = NULL;
    const size_t bufsz = 4096;
    char *buf = NULL;
	size_t mapmax = 0;
	size_t mapnum = 0;
	struct ld_procmaps *maps = NULL;
	if (pid == 0) {
		LOG_ERROR_INVALID_PID(pid);
		return NULL;
	}
	snprintf(filename, OS_MAX_BUFFER, "/proc/%d/maps", pid);
	snprintf(appname, OS_MAX_BUFFER, "/proc/%d/exe", pid);
	if (verbose > 2) {
		fprintf(stderr, "[%s:%d] Using Proc Maps from %s\n", __func__,
				__LINE__, filename);
		fprintf(stderr, "[%s:%d] Using Proc Exe from %s\n", __func__,
				__LINE__, appname);
	}
	do {
		buf = calloc(sizeof(char), bufsz);
		if (!buf) {
			LOG_ERROR_OUT_OF_MEMORY;
			break;
		}
		ff = fopen(filename, "r");
		if (!ff) {
			LOG_ERROR_FILE_OPEN(filename);
			break;
		}
		while (fgets(buf, bufsz, ff))
			mapmax++;
		if (verbose > 0)
			fprintf(stderr, "[%s:%d] Max number of mappings present: "LU"\n",
					__func__, __LINE__, mapmax);
		fseek(ff, 0L, SEEK_SET);
		maps = calloc(sizeof(*maps), mapmax);
		if (!maps) {
			LOG_ERROR_OUT_OF_MEMORY;
			break;
		}
		if (verbose > 1)
			fprintf(stderr,
					"[%s:%d] Allocated memory to load proc maps.\n",
					__func__, __LINE__);
		memset(buf, 0, bufsz);
		mapnum = 0;
		while (fgets(buf, bufsz, ff)) {
			struct ld_procmaps *pm = &maps[mapnum];
			if (verbose > 3)
				fprintf(stderr, "[%s:%d] Parsing %s\n", __func__, __LINE__,
						buf);
			if (ld_procmaps_parse(buf, bufsz, pm, appname, verbose) < 0) {
				if (verbose > 1) {
					fprintf(stderr, "[%s:%d] Parsing failure. Ignoring.\n",
							__func__, __LINE__);
				}
				continue;
			}
			if (verbose > 4)
				ld_procmaps_dump(pm);
			mapnum++;
		}
		if (num)
			*num = mapnum;
		else
			if (verbose > 3)
				fprintf(stderr, "[%s:%d] Cannot return size of maps object.\n",
						__func__, __LINE__);
	} while (0);
	if (buf)
	    free(buf);
	if (ff)
	    fclose(ff);
	return maps;
}
Exemple #2
0
hotpatch_t *hotpatch_create(pid_t pid, int verbose)
{
	int rc = 0;
	hotpatch_t *hp = NULL;
	do {
		char filename[OS_MAX_BUFFER];
		if (pid <= 0) {
			LOG_ERROR_INVALID_PID(pid);
			break;
		}
		memset(filename, 0, sizeof(filename));
		snprintf(filename, sizeof(filename), "/proc/%d/exe", pid);
		if (verbose > 3)
			fprintf(stderr, "[%s:%d] Exe symlink for pid %d : %s\n", __func__,
					__LINE__, pid, filename);
		hp = malloc(sizeof(*hp));
		if (!hp) {
			LOG_ERROR_OUT_OF_MEMORY;
			rc = -1;
			break;
		}
		memset(hp, 0, sizeof(*hp));
		hp->verbose = verbose;
		hp->pid = pid;
		hp->is64 = HOTPATCH_EXE_IS_NEITHER;
		hp->exe_symbols = exe_load_symbols(filename, hp->verbose,
				&hp->exe_symbols_num,
				&hp->exe_entry_point,
				&hp->exe_interp,
				&hp->is64);
		if (!hp->exe_symbols) {
			fprintf(stderr, "[%s:%d] Unable to find any symbols in exe.\n",
					__func__, __LINE__);
			rc = -1;
			break;
		}
		if (hp->exe_entry_point == 0) {
			fprintf(stderr, "[%s:%d] Entry point is 0. Invalid.\n",
					__func__, __LINE__);
			rc = -1;
			break;
		}
		LOG_INFO_HEADERS_LOADED(verbose);
		hp->ld_maps = ld_load_maps(hp->pid, hp->verbose, &hp->ld_maps_num);
		if (!hp->ld_maps) {
			fprintf(stderr, "[%s:%d] Unable to load data in "
					"/proc/%d/maps.\n", __func__, __LINE__, pid);
			rc = -1;
			break;
		}
		if (verbose > 2)
			fprintf(stderr, "[%s:%d] /proc/%d/maps loaded.\n",
					__func__, __LINE__, pid);
		if (hp->exe_symbols && hp->exe_symbols_num > 0) {
			qsort(hp->exe_symbols, hp->exe_symbols_num,
					sizeof(*hp->exe_symbols), elf_symbol_cmpqsort);
		}
		if (hotpatch_gather_functions(hp) < 0) {
			fprintf(stderr, "[%s:%d] Unable to find all the functions"
					" needed. Cannot proceed.\n", __func__, __LINE__);
			rc = -1;
			break;
		}
		if (rc < 0) {
			hotpatch_destroy(hp);
			hp = NULL;
		}
	} while (0);
	return hp;
}