|
|
c0fbae |
#include <stdint.h>
|
|
|
c0fbae |
#include <stdio.h>
|
|
|
c0fbae |
#include <stdlib.h>
|
|
|
c0fbae |
#include <string.h>
|
|
|
c0fbae |
#include <malloc.h>
|
|
|
c0fbae |
#include <unistd.h>
|
|
|
c0fbae |
#include <fcntl.h>
|
|
|
c0fbae |
#include <limits.h>
|
|
|
c0fbae |
#include <errno.h>
|
|
|
c0fbae |
#include <sys/mman.h>
|
|
|
c0fbae |
#include <sys/types.h>
|
|
|
c0fbae |
#include <sys/stat.h>
|
|
|
c0fbae |
|
|
|
c0fbae |
#include <perk/perk.h>
|
|
|
c0fbae |
#include "perk_impl.h"
|
|
|
c0fbae |
|
|
|
c0fbae |
static int perk_parse_opts(struct perk_ctx * ctx)
|
|
|
c0fbae |
{
|
|
|
c0fbae |
int i;
|
|
|
c0fbae |
char * ch;
|
|
|
c0fbae |
const char ** popt;
|
|
|
c0fbae |
|
|
|
c0fbae |
for (i=1; i<ctx->argc; i++) {
|
|
|
c0fbae |
ch = ctx->argv[i];
|
|
|
c0fbae |
|
|
|
c0fbae |
if (*ch == '-') {
|
|
|
c0fbae |
switch (*++ch) {
|
|
|
c0fbae |
case 'i':
|
|
|
c0fbae |
popt = &ctx->fname;
|
|
|
c0fbae |
break;
|
|
|
c0fbae |
case 'h':
|
|
|
c0fbae |
ctx->flags = PERK_HELP;
|
|
|
c0fbae |
return 0;
|
|
|
c0fbae |
default:
|
|
|
c0fbae |
ctx->status = PERK_BAD_OPT;
|
|
|
c0fbae |
return ctx->status;
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
while ((*++ch == '\t') || (*ch == ' '));
|
|
|
c0fbae |
|
|
|
c0fbae |
if (!*ch) {
|
|
|
c0fbae |
if (++i < ctx->argc)
|
|
|
c0fbae |
*popt = ctx->argv[i];
|
|
|
c0fbae |
else
|
|
|
c0fbae |
ctx->status = PERK_BAD_OPT_VAL;
|
|
|
c0fbae |
} else
|
|
|
c0fbae |
*popt = ch;
|
|
|
c0fbae |
} else if (!ctx->fname)
|
|
|
c0fbae |
ctx->fname = ch;
|
|
|
c0fbae |
else
|
|
|
c0fbae |
ctx->status = PERK_BAD_OPT;
|
|
|
c0fbae |
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
return ctx->status;
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
|
|
|
c0fbae |
static int perk_map_input(struct perk_ctx * ctx)
|
|
|
c0fbae |
{
|
|
|
c0fbae |
ctx->fd = open(ctx->fname,O_RDONLY | O_CLOEXEC);
|
|
|
c0fbae |
|
|
|
c0fbae |
if (ctx->fd < 0) {
|
|
|
c0fbae |
ctx->status = PERK_IO_ERROR;
|
|
|
c0fbae |
return ctx->status;
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
ctx->status = pe_map_raw_image(ctx->fd,0,&ctx->map);
|
|
|
c0fbae |
|
|
|
c0fbae |
return ctx->status;
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
|
|
|
c0fbae |
static int perk_exit(struct perk_ctx * ctx)
|
|
|
c0fbae |
{
|
|
|
c0fbae |
if (ctx->map.addr)
|
|
|
c0fbae |
pe_unmap_raw_image(&ctx->map);
|
|
|
c0fbae |
|
|
|
c0fbae |
return ctx->status;
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
|
|
|
c0fbae |
static int perk_run(struct perk_ctx * ctx)
|
|
|
c0fbae |
{
|
|
|
c0fbae |
struct pe_image_meta * meta;
|
|
|
c0fbae |
|
|
|
c0fbae |
if (perk_map_input(ctx))
|
|
|
c0fbae |
return perk_exit(ctx);
|
|
|
c0fbae |
|
|
|
c0fbae |
if ((ctx->status = pe_get_image_meta(&ctx->map,&meta)))
|
|
|
c0fbae |
return perk_exit(ctx);
|
|
|
c0fbae |
|
|
|
c0fbae |
/* pre-alpha default output */
|
|
|
c0fbae |
pe_output_export_symbols(
|
|
|
c0fbae |
meta,
|
|
|
c0fbae |
PERK_OUTPUT_FORMAT_LIST | PERK_OUTPUT_FIELD_NAME,
|
|
|
c0fbae |
stdout);
|
|
|
c0fbae |
|
|
|
c0fbae |
ctx->status = pe_free_image_meta(meta);
|
|
|
c0fbae |
|
|
|
c0fbae |
return perk_exit(ctx);
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
static int perk_main(int argc, char * argv[], char * envp[])
|
|
|
c0fbae |
{
|
|
|
c0fbae |
struct perk_ctx ctx = {argc,argv,envp};
|
|
|
c0fbae |
|
|
|
c0fbae |
if (perk_parse_opts(&ctx))
|
|
|
c0fbae |
return ctx.status;
|
|
|
c0fbae |
else
|
|
|
c0fbae |
return perk_run(&ctx;;
|
|
|
c0fbae |
}
|
|
|
c0fbae |
|
|
|
c0fbae |
#ifdef PERK_APP
|
|
|
c0fbae |
extern __typeof(perk_main) main __attribute__((alias("perk_main")));
|
|
|
c0fbae |
#endif
|