summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mdso/mdso.h9
-rw-r--r--src/archive/mdso_argen_common.c12
-rw-r--r--src/helper/mdso_create_output.c53
-rw-r--r--src/object/mdso_objgen_dsometa.c38
-rw-r--r--src/object/mdso_objgen_symentry.c38
-rw-r--r--src/object/mdso_objgen_symfn.c38
-rw-r--r--src/util/mdso_create_implib_objects.c42
7 files changed, 136 insertions, 94 deletions
diff --git a/include/mdso/mdso.h b/include/mdso/mdso.h
index a0ecb0e..7927896 100644
--- a/include/mdso/mdso.h
+++ b/include/mdso/mdso.h
@@ -87,6 +87,7 @@ struct mdso_fd_ctx {
};
struct mdso_object {
+ const char * name;
void * addr;
size_t size;
char * mapstrs;
@@ -159,7 +160,7 @@ mdso_api int mdso_set_driver_fdctx (struct mdso_driver_ctx *, const struct
/* helper api */
mdso_api FILE*mdso_create_archive (const struct mdso_driver_ctx *, const char * arname);
mdso_api int mdso_create_asmsrc (const struct mdso_driver_ctx *, const char * asmname);
-mdso_api FILE*mdso_create_object (const struct mdso_driver_ctx *, const char * objname);
+mdso_api int mdso_create_object (const struct mdso_driver_ctx *, struct mdso_object *);
/* utility api */
mdso_api int mdso_main (int, char **, char **, const struct mdso_fd_ctx *);
@@ -185,9 +186,9 @@ mdso_api int mdso_asmgen_dsometa (const struct mdso_driver_ctx *, int);
mdso_api int mdso_asmgen_symentry (const struct mdso_driver_ctx *, const char *, int);
mdso_api int mdso_asmgen_symfn (const struct mdso_driver_ctx *, const char *, int);
-mdso_api int mdso_objgen_dsometa (const struct mdso_driver_ctx *, FILE *, struct mdso_object *);
-mdso_api int mdso_objgen_symentry (const struct mdso_driver_ctx *, const char *, FILE *, struct mdso_object *);
-mdso_api int mdso_objgen_symfn (const struct mdso_driver_ctx *, const char *, FILE *, struct mdso_object *);
+mdso_api int mdso_objgen_dsometa (const struct mdso_driver_ctx *, struct mdso_object *);
+mdso_api int mdso_objgen_symentry (const struct mdso_driver_ctx *, const char *, struct mdso_object *);
+mdso_api int mdso_objgen_symfn (const struct mdso_driver_ctx *, const char *, struct mdso_object *);
mdso_api int mdso_argen_common (const struct mdso_driver_ctx *,
const char **, const int *,
diff --git a/src/archive/mdso_argen_common.c b/src/archive/mdso_argen_common.c
index 3cae712..62cca47 100644
--- a/src/archive/mdso_argen_common.c
+++ b/src/archive/mdso_argen_common.c
@@ -93,7 +93,7 @@ int mdso_argen_common(
objlen += sizeof(struct pe_raw_archive_common_hdr);
/* objlen: member headers */
- ret = mdso_objgen_dsometa(dctx,0,aobj);
+ ret = mdso_objgen_dsometa(dctx,aobj);
aobj->size += 1;
aobj->size |= 1;
@@ -107,7 +107,7 @@ int mdso_argen_common(
for (psym=symv,pobj=&aobj[1]; *psym && !ret; psym++) {
if (stype[psym-symv] == MDSO_SYMBOL_TYPE_CODE) {
- ret = mdso_objgen_symfn(dctx,*psym,0,pobj);
+ ret = mdso_objgen_symfn(dctx,*psym,pobj);
pobj->size += 1;
pobj->size |= 1;
@@ -121,7 +121,7 @@ int mdso_argen_common(
pobj++;
}
- ret |= mdso_objgen_symentry(dctx,*psym,0,pobj);
+ ret |= mdso_objgen_symentry(dctx,*psym,pobj);
pobj->size += 1;
pobj->size |= 1;
@@ -205,7 +205,7 @@ int mdso_argen_common(
idx += sizeof(uint32_t);
}
- ret = mdso_objgen_dsometa(dctx,0,aobj);
+ ret = mdso_objgen_dsometa(dctx,aobj);
mdso_argen_common_hdr(
(struct pe_raw_archive_common_hdr *)mark,
@@ -228,7 +228,7 @@ int mdso_argen_common(
idx += sizeof(uint32_t);
}
- ret = mdso_objgen_symfn(dctx,*psym,0,pobj);
+ ret = mdso_objgen_symfn(dctx,*psym,pobj);
sprintf(
objname,"f%06zu.o",
@@ -259,7 +259,7 @@ int mdso_argen_common(
objname,"s%06zu.o",
psym - symv);
- ret = mdso_objgen_symentry(dctx,*psym,0,pobj);
+ ret = mdso_objgen_symentry(dctx,*psym,pobj);
mdso_argen_common_hdr(
(struct pe_raw_archive_common_hdr *)mark,
diff --git a/src/helper/mdso_create_output.c b/src/helper/mdso_create_output.c
index 24ed757..39dd4d7 100644
--- a/src/helper/mdso_create_output.c
+++ b/src/helper/mdso_create_output.c
@@ -10,6 +10,7 @@
#include <stddef.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/mman.h>
#include <mdso/mdso.h>
#include "mdso_driver_impl.h"
@@ -25,13 +26,40 @@ static int mdso_create_output(
fddst = mdso_driver_fddst(dctx);
if ((fdout = openat(fddst,name,
- O_CREAT|O_TRUNC|O_WRONLY|O_NOCTTY|O_NOFOLLOW,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
+ O_CREAT|O_TRUNC|O_WRONLY|O_NOCTTY|O_NOFOLLOW,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
return MDSO_SYSTEM_ERROR(dctx);
return fdout;
}
+static int mdso_map_output(
+ const struct mdso_driver_ctx * dctx,
+ struct mdso_object * obj,
+ int fd)
+{
+ void * addr;
+
+ if (ftruncate(fd,obj->size)) {
+ close(fd);
+ return MDSO_SYSTEM_ERROR(dctx);
+ }
+
+ addr = mmap(
+ 0,obj->size,
+ PROT_WRITE,MAP_SHARED,
+ fd,0);
+
+ close(fd);
+
+ if (addr == MAP_FAILED)
+ return MDSO_SYSTEM_ERROR(dctx);
+
+ obj->addr = addr;
+
+ return 0;
+}
+
static FILE * mdso_create_output_stream(
const struct mdso_driver_ctx * dctx,
const char * name)
@@ -51,6 +79,21 @@ static FILE * mdso_create_output_stream(
return fout;
}
+static int mdso_create_mapped_output(
+ const struct mdso_driver_ctx * dctx,
+ struct mdso_object * obj)
+{
+ int fd;
+
+ if ((fd = mdso_create_output(dctx,obj->name)) < 0)
+ return MDSO_NESTED_ERROR(dctx);
+
+ if (mdso_map_output(dctx,obj,fd) < 0)
+ return MDSO_NESTED_ERROR(dctx);
+
+ return 0;
+}
+
FILE * mdso_create_archive(
const struct mdso_driver_ctx * dctx,
const char * arname)
@@ -67,9 +110,9 @@ int mdso_create_asmsrc(
: mdso_driver_fdout(dctx);
}
-FILE * mdso_create_object(
+int mdso_create_object(
const struct mdso_driver_ctx * dctx,
- const char * objname)
+ struct mdso_object * obj)
{
- return mdso_create_output_stream(dctx,objname);
+ return mdso_create_mapped_output(dctx,obj);
}
diff --git a/src/object/mdso_objgen_dsometa.c b/src/object/mdso_objgen_dsometa.c
index dfe8a33..388e296 100644
--- a/src/object/mdso_objgen_dsometa.c
+++ b/src/object/mdso_objgen_dsometa.c
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <mdso/mdso.h>
#include <mdso/mdso_specs.h>
@@ -32,11 +33,11 @@ struct mdso_dsometa_object {
int mdso_objgen_dsometa(
const struct mdso_driver_ctx * dctx,
- FILE * fout,
struct mdso_object * vobj)
{
struct mdso_dsometa_object * dsometa;
struct pe_raw_coff_symbol * symrec;
+ void * addr;
unsigned char * mark;
struct pe_raw_aux_rec_section * aux;
size_t buflen;
@@ -65,21 +66,25 @@ int mdso_objgen_dsometa(
cstlen = (3 * liblen) + 48;
objlen = sizeof(*dsometa) + cstlen;
- if (vobj && vobj->addr && (vobj->size < objlen))
+ if (vobj->addr && (vobj->size < objlen))
return MDSO_BUFFER_ERROR(dctx);
- if (vobj && !vobj->addr) {
- vobj->size = objlen;
+ if ((addr = vobj->addr)) {
+ (void)0;
+
+ } else {
+ vobj->size = objlen;
vobj->mapstrsnum = 1;
vobj->mapstrslen = 10 + liblen;
- return 0;
- }
- if (vobj)
- dsometa = (struct mdso_dsometa_object *)vobj->addr;
+ if (!vobj->name)
+ return 0;
+
+ else if (mdso_create_object(dctx,vobj) < 0)
+ return MDSO_NESTED_ERROR(dctx);
+ }
- else if (!(dsometa = calloc(1,objlen)))
- return MDSO_SYSTEM_ERROR(dctx);
+ dsometa = (struct mdso_dsometa_object *)vobj->addr;
if (dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR) {
reclen = sizeof(struct mdso_meta_record_m64);
@@ -220,20 +225,17 @@ int mdso_objgen_dsometa(
memcpy(&mark[9],dctx->cctx->libname,liblen);
/* archive symbol map */
- if (vobj && vobj->mapstrs)
+ if (vobj->mapstrs)
memcpy(vobj->mapstrs,mark,9+liblen);
/* .libname */
mark = dsometa->hdr.cfh_machine;
memcpy(&mark[stroff],dctx->cctx->libname,liblen);
- /* tada */
- if (fout)
- if (fwrite(dsometa,objlen,1,fout) == 0)
- return MDSO_FILE_ERROR(dctx);
-
- if (!vobj)
- free(dsometa);
+ /* fs object unmap */
+ if (!addr)
+ munmap(vobj->addr,vobj->size);
+ /* tada */
return 0;
}
diff --git a/src/object/mdso_objgen_symentry.c b/src/object/mdso_objgen_symentry.c
index 47167c7..7ddc14c 100644
--- a/src/object/mdso_objgen_symentry.c
+++ b/src/object/mdso_objgen_symentry.c
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <mdso/mdso.h>
#include "mdso_object_impl.h"
@@ -32,11 +33,11 @@ struct mdso_symentry_object {
int mdso_objgen_symentry(
const struct mdso_driver_ctx * dctx,
const char * sym,
- FILE * fout,
struct mdso_object * vobj)
{
struct mdso_symentry_object * syment;
struct pe_raw_coff_symbol * symrec;
+ void * addr;
unsigned char * mark;
unsigned char * mapsym;
struct pe_raw_aux_rec_section * aux;
@@ -71,21 +72,25 @@ int mdso_objgen_symentry(
objlen = sizeof(*syment) + cstlen;
uscore = !(dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR);
- if (vobj && vobj->addr && (vobj->size < objlen))
+ if (vobj->addr && (vobj->size < objlen))
return MDSO_BUFFER_ERROR(dctx);
- if (vobj && !vobj->addr) {
- vobj->size = objlen;
+ if ((addr = vobj->addr)) {
+ (void)0;
+
+ } else {
+ vobj->size = objlen;
vobj->mapstrsnum = 1;
vobj->mapstrslen = 7 + uscore + symlen;
- return 0;
- }
- if (vobj)
- syment = (struct mdso_symentry_object *)vobj->addr;
+ if (!vobj->name)
+ return 0;
+
+ else if (mdso_create_object(dctx,vobj) < 0)
+ return MDSO_NESTED_ERROR(dctx);
+ }
- else if (!(syment = calloc(1,objlen)))
- return MDSO_SYSTEM_ERROR(dctx);
+ syment = (struct mdso_symentry_object *)vobj->addr;
if (dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR) {
aattr = PE_IMAGE_SCN_ALIGN_16BYTES;
@@ -238,7 +243,7 @@ int mdso_objgen_symentry(
symrec += 1;
/* archive symbol map */
- if (vobj && vobj->mapstrs)
+ if (vobj->mapstrs)
memcpy(vobj->mapstrs,mapsym,mark-mapsym);
/* coff symbol: .dsometa_libname */
@@ -255,13 +260,10 @@ int mdso_objgen_symentry(
mark = syment->hdr.cfh_machine;
memcpy(&mark[stroff],sym,symlen);
- /* tada */
- if (fout)
- if (fwrite(syment,objlen,1,fout) == 0)
- return MDSO_FILE_ERROR(dctx);
-
- if (!vobj)
- free(syment);
+ /* fs object unmap */
+ if (!addr)
+ munmap(vobj->addr,vobj->size);
+ /* tada */
return 0;
}
diff --git a/src/object/mdso_objgen_symfn.c b/src/object/mdso_objgen_symfn.c
index 47f9280..6f4ac68 100644
--- a/src/object/mdso_objgen_symfn.c
+++ b/src/object/mdso_objgen_symfn.c
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <mdso/mdso.h>
#include "mdso_object_impl.h"
@@ -46,12 +47,12 @@ struct mdso_symfn_object {
int mdso_objgen_symfn(
const struct mdso_driver_ctx * dctx,
const char * sym,
- FILE * fout,
struct mdso_object * vobj)
{
struct mdso_symfn_object * symfn;
struct pe_raw_coff_symbol * symrec;
const unsigned char * code;
+ void * addr;
unsigned char * mark;
unsigned char * mapsym;
struct pe_raw_aux_rec_section * aux;
@@ -80,21 +81,25 @@ int mdso_objgen_symfn(
objlen = sizeof(*symfn) + cstlen;
uscore = !(dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR);
- if (vobj && vobj->addr && (vobj->size < objlen))
+ if (vobj->addr && (vobj->size < objlen))
return MDSO_BUFFER_ERROR(dctx);
- if (vobj && !vobj->addr) {
- vobj->size = objlen;
+ if ((addr = vobj->addr)) {
+ (void)0;
+
+ } else {
+ vobj->size = objlen;
vobj->mapstrsnum = 1;
vobj->mapstrslen = 1 + uscore + symlen;
- return 0;
- }
- if (vobj)
- symfn = (struct mdso_symfn_object *)vobj->addr;
+ if (!vobj->name)
+ return 0;
+
+ else if (mdso_create_object(dctx,vobj) < 0)
+ return MDSO_NESTED_ERROR(dctx);
+ }
- else if (!(symfn = calloc(1,objlen)))
- return MDSO_SYSTEM_ERROR(dctx);
+ symfn = (struct mdso_symfn_object *)vobj->addr;
if (dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR) {
code = jmp_code_amd64;
@@ -206,7 +211,7 @@ int mdso_objgen_symfn(
symrec += 2;
/* archive symbol map */
- if (vobj && vobj->mapstrs)
+ if (vobj->mapstrs)
memcpy(vobj->mapstrs,mapsym,mark-mapsym);
/* coff symbol: __imp_sym */
@@ -227,13 +232,10 @@ int mdso_objgen_symfn(
mark++;
}
- /* tada */
- if (fout)
- if (fwrite(symfn,objlen,1,fout) == 0)
- return MDSO_FILE_ERROR(dctx);
-
- if (!vobj)
- free(symfn);
+ /* fs object unmap */
+ if (!addr)
+ munmap(vobj->addr,vobj->size);
+ /* tada */
return 0;
}
diff --git a/src/util/mdso_create_implib_objects.c b/src/util/mdso_create_implib_objects.c
index 5740109..43f79ee 100644
--- a/src/util/mdso_create_implib_objects.c
+++ b/src/util/mdso_create_implib_objects.c
@@ -24,14 +24,19 @@ static void mdso_init_objname(char * buf, const char * fmt, const char * str)
sprintf(buf,fmt,str);
}
-mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx)
+static void mdso_init_object(struct mdso_object * obj, const char * objname)
+{
+ memset(obj,0,sizeof(*obj));
+ obj->name = objname;
+}
+
+int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx)
{
- struct mdso_unit_ctx * uctx;
const char ** unit;
- FILE * fout;
- char objname[PATH_MAX];
+ struct mdso_unit_ctx * uctx;
+ struct mdso_object obj;
const char * const * sym;
- int ret;
+ char objname[PATH_MAX];
/* symentry, symfn */
for (unit=dctx->units; *unit; unit++) {
@@ -40,26 +45,16 @@ mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx)
for (sym=uctx->syms; *sym; sym++) {
mdso_init_objname(objname,".%s_symentry.o",*sym);
+ mdso_init_object(&obj,objname);
- if (!(fout = mdso_create_object(dctx,objname)))
- return MDSO_NESTED_ERROR(dctx);
-
- ret = mdso_objgen_symentry(dctx,*sym,fout,0);
- fclose(fout);
-
- if (ret < 0)
+ if (mdso_objgen_symentry(dctx,*sym,&obj) < 0)
return MDSO_NESTED_ERROR(dctx);
if (uctx->stype[sym-uctx->syms] == MDSO_SYMBOL_TYPE_CODE) {
mdso_init_objname(objname,".%s_symfn.o",*sym);
+ mdso_init_object(&obj,objname);
- if (!(fout = mdso_create_object(dctx,objname)))
- return MDSO_NESTED_ERROR(dctx);
-
- ret = mdso_objgen_symfn(dctx,*sym,fout,0);
- fclose(fout);
-
- if (ret < 0)
+ if (mdso_objgen_symfn(dctx,*sym,&obj) < 0)
return MDSO_NESTED_ERROR(dctx);
}
}
@@ -69,13 +64,10 @@ mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx)
/* dsometa */
mdso_init_objname(objname,".dsometa_%s.o",dctx->cctx->libname);
+ mdso_init_object(&obj,objname);
- if (!(fout = mdso_create_object(dctx,objname)))
+ if (mdso_objgen_dsometa(dctx,&obj) < 0)
return MDSO_NESTED_ERROR(dctx);
- ret = mdso_objgen_dsometa(dctx,fout,0);
- fclose(fout);
-
- return (ret < 0) ? MDSO_NESTED_ERROR(dctx) : 0;
-
+ return 0;
}