Blame src/driver/pe_unit_ctx.c

e2e2c2
/***************************************************************/
e2e2c2
/*  perk: PE Resource Kit                                      */
e2e2c2
/*  Copyright (C) 2015--2016  Z. Gilboa                        */
e2e2c2
/*  Released under GPLv2 and GPLv3; see COPYING.PERK.          */
e2e2c2
/***************************************************************/
e2e2c2
81e8b3
#include <stdint.h>
d7ed3e
#include <stddef.h>
81e8b3
#include <stdlib.h>
81e8b3
#include <string.h>
81e8b3
#include <sys/mman.h>
d7ed3e
81e8b3
#include <perk/perk.h>
eb4c04
#include "perk_driver_impl.h"
9b7081
#include "perk_errinfo_impl.h"
81e8b3
9b7081
static int pe_free_unit_ctx_impl(struct pe_unit_ctx_impl * ctx, int ret)
81e8b3
{
81e8b3
	if (ctx) {
81e8b3
		pe_free_image_meta(ctx->meta);
81e8b3
		pe_unmap_raw_image(&ctx->map);
81e8b3
		free(ctx);
81e8b3
	}
81e8b3
9b7081
	return ret;
81e8b3
}
81e8b3
81e8b3
int pe_get_unit_ctx(
a9788e
	const struct pe_driver_ctx *	dctx,
a9788e
	const char *			path,
a9788e
	struct pe_unit_ctx **		pctx)
81e8b3
{
d7ed3e
	struct pe_unit_ctx_impl *	ctx;
720609
	int				prot;
81e8b3
9b7081
	if (!dctx)
cee41b
		return PERK_CUSTOM_ERROR(
cee41b
			dctx,PERK_ERR_NULL_CONTEXT);
9b7081
9b7081
	else if (!(ctx = calloc(1,sizeof(*ctx))))
9b7081
		return PERK_BUFFER_ERROR(dctx);
81e8b3
c29b50
	pe_driver_set_ectx(
c29b50
		dctx,0,path);
c29b50
c61328
	prot = (dctx->cctx->actflags & PERK_ACTION_MAP_READWRITE)
81e8b3
		? PROT_READ | PROT_WRITE
81e8b3
		: PROT_READ;
81e8b3
f11c1f
	if (pe_map_raw_image(dctx,-1,path,prot,&ctx->map))
9b7081
		return pe_free_unit_ctx_impl(ctx,
cee41b
			PERK_NESTED_ERROR(dctx));
81e8b3
0e3fd6
	if (pe_get_image_meta(dctx,&ctx->map,&ctx->meta))
9b7081
		return pe_free_unit_ctx_impl(ctx,
9b7081
			PERK_NESTED_ERROR(dctx));
81e8b3
72cb99
	ctx->path	= path;
d7ed3e
	ctx->uctx.path	= &ctx->path;
d7ed3e
	ctx->uctx.map	= &ctx->map;
d7ed3e
	ctx->uctx.meta	= ctx->meta;
d7ed3e
d7ed3e
	*pctx = &ctx->uctx;
81e8b3
	return 0;
81e8b3
}
81e8b3
81e8b3
void pe_free_unit_ctx(struct pe_unit_ctx * ctx)
81e8b3
{
d7ed3e
	struct pe_unit_ctx_impl *	ictx;
d7ed3e
	uintptr_t			addr;
d7ed3e
d7ed3e
	if (ctx) {
d7ed3e
		addr = (uintptr_t)ctx - offsetof(struct pe_unit_ctx_impl,uctx);
d7ed3e
		ictx = (struct pe_unit_ctx_impl *)addr;
d7ed3e
		pe_free_unit_ctx_impl(ictx,0);
d7ed3e
	}
81e8b3
}