diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/driver/mdso_unit_ctx.c | 87 | ||||
-rw-r--r-- | src/internal/mdso_driver_impl.h | 6 |
2 files changed, 93 insertions, 0 deletions
diff --git a/src/driver/mdso_unit_ctx.c b/src/driver/mdso_unit_ctx.c index d955f7f..d46820b 100644 --- a/src/driver/mdso_unit_ctx.c +++ b/src/driver/mdso_unit_ctx.c @@ -18,6 +18,12 @@ static int mdso_free_unit_ctx_impl(struct mdso_unit_ctx_impl * ctx, int status) { if (ctx) { + if (ctx->expsyms && ctx->expsyms->buffer) + free(ctx->expsyms->buffer); + + if (ctx->expsyms) + free(ctx->expsyms); + mdso_unmap_input(&ctx->map); free(ctx); } @@ -55,6 +61,83 @@ static FILE * mdso_stdin_to_tmp(void) return ftmp; } +static int mdso_create_symbol_vector(struct mdso_unit_ctx_impl * ctx) +{ + int nsyms; + size_t nbytes; + size_t size; + char * dst; + const char * ch; + const char ** sym; + + const char exphdr[] = "EXPORTS\n"; + const char imphdr[] = "IMPORTS\n"; + + ch = ctx->map.addr; + nbytes = ctx->map.size; + + for (nsyms=0; nbytes; ch++,nbytes--) + nsyms += (*ch == '\n'); + + size = offsetof(struct mdso_unit_ctx_impl,expsyms); + size += (nsyms+1)*sizeof(const char *); + + if (!(ctx->expsyms = calloc(size,1))) + return -1; + + if (!(ctx->expsyms->buffer = calloc(ctx->map.size,1))) + return -1; + + ch = ctx->map.addr; + nbytes = ctx->map.size; + sym = ctx->expsyms->syms; + dst = ctx->expsyms->buffer; + size = strlen(exphdr); + + /* support .def input files */ + if ((nbytes >= size) && !(strncmp(ch,exphdr,size))) { + ch += size; + nbytes -= size; + } + + /* advance to first symbol */ + for (; nbytes && ((*ch==' ') + || (*ch=='\t') + || (*ch=='\r') + || (*ch=='\n')); nbytes--) + ch++; + + /* support .def input files */ + size = strlen(imphdr); + + while (nbytes && ((nbytes < size) || (strncmp(ch,imphdr,size)))) { + /* vector */ + *sym++ = dst; + + /* symbol */ + for (; nbytes && ((*ch!=' ') + && (*ch!='\t') + && (*ch!='\r') + && (*ch!='\n')); nbytes--) + *dst++ = *ch++; + + dst++; + + /* discard rest of input line */ + for (; nbytes && (*ch!='\n'); nbytes--) + ch++; + + /* advance to next symbol */ + for (; nbytes && ((*ch==' ') + || (*ch=='\t') + || (*ch=='\r') + || (*ch=='\n')); nbytes--) + ch++; + } + + return 0; +} + int mdso_get_unit_ctx( const struct mdso_driver_ctx * dctx, const char * path, @@ -82,6 +165,9 @@ int mdso_get_unit_ctx( if (fd > 0) close(fd); + if (mdso_create_symbol_vector(ctx)) + return mdso_free_unit_ctx_impl(ctx,-1); + memcpy(&ctx->cctx,dctx->cctx, sizeof(ctx->cctx)); @@ -90,6 +176,7 @@ int mdso_get_unit_ctx( ctx->uctx.path = &ctx->path; ctx->uctx.map = &ctx->map; ctx->uctx.cctx = &ctx->cctx; + ctx->uctx.syms = ctx->expsyms->syms; *pctx = &ctx->uctx; return 0; diff --git a/src/internal/mdso_driver_impl.h b/src/internal/mdso_driver_impl.h index 2c4554f..aa09197 100644 --- a/src/internal/mdso_driver_impl.h +++ b/src/internal/mdso_driver_impl.h @@ -12,6 +12,11 @@ enum app_tags { TAG_VERSION, }; +struct mdso_expsyms { + char * buffer; + const char * syms[]; +}; + struct mdso_driver_ctx_impl { struct mdso_common_ctx cctx; struct mdso_driver_ctx ctx; @@ -20,6 +25,7 @@ struct mdso_driver_ctx_impl { struct mdso_unit_ctx_impl { const char * path; struct mdso_input map; + struct mdso_expsyms * expsyms; struct mdso_common_ctx cctx; struct mdso_unit_ctx uctx; }; |