#include "pt_sb_context.h"
#include "pt_sb_session.h"
#include "libipt-sb.h"
#include "intel-pt.h"
#include <stdlib.h>
struct pt_sb_context *pt_sb_ctx_alloc(const char *name)
{
struct pt_sb_context *context;
struct pt_image *image;
image = pt_image_alloc(name);
if (!image)
return NULL;
context = malloc(sizeof(*context));
if (!context) {
pt_image_free(image);
return NULL;
}
memset(context, 0, sizeof(*context));
context->image = image;
context->ucount = 1;
return context;
}
int pt_sb_ctx_get(struct pt_sb_context *context)
{
uint16_t ucount;
if (!context)
return -pte_invalid;
ucount = context->ucount;
if (UINT16_MAX <= ucount)
return -pte_overflow;
context->ucount = ucount + 1;
return 0;
}
static void pt_sb_ctx_free(struct pt_sb_context *context)
{
if (!context)
return;
pt_image_free(context->image);
free(context);
}
int pt_sb_ctx_put(struct pt_sb_context *context)
{
uint16_t ucount;
if (!context)
return -pte_invalid;
ucount = context->ucount;
if (ucount > 1) {
context->ucount = ucount - 1;
return 0;
}
if (!ucount)
return -pte_internal;
pt_sb_ctx_free(context);
return 0;
}
struct pt_image *pt_sb_ctx_image(const struct pt_sb_context *context)
{
if (!context)
return NULL;
return context->image;
}
int pt_sb_ctx_mmap(struct pt_sb_session *session, struct pt_sb_context *context,
const char *filename, uint64_t offset, uint64_t size,
uint64_t vaddr)
{
struct pt_image_section_cache *iscache;
struct pt_image *image;
int isid;
image = pt_sb_ctx_image(context);
if (!image)
return -pte_internal;
iscache = pt_sb_iscache(session);
if (!iscache)
return pt_image_add_file(image, filename, offset, size, NULL,
vaddr);
isid = pt_iscache_add_file(iscache, filename, offset, size, vaddr);
if (isid < 0)
return isid;
return pt_image_add_cached(image, iscache, isid, NULL);
}
int pt_sb_ctx_switch_to(struct pt_image **pimage, struct pt_sb_session *session,
const struct pt_sb_context *context)
{
pt_sb_ctx_switch_notifier_t *notify_switch_to;
struct pt_image *image;
int errcode;
if (!pimage || !session)
return -pte_internal;
image = pt_sb_ctx_image(context);
if (!image)
return -pte_internal;
notify_switch_to = session->notify_switch_to;
if (notify_switch_to) {
errcode = notify_switch_to(context, session->priv_switch_to);
if (errcode < 0)
return errcode;
}
*pimage = image;
return 0;
}