2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * ncval.c - command line validator for NaCl.
45 #include "native_client/include/nacl_elf.h"
49 #include <sys/timeb.h>
51 #include "ncfileutil.h"
52 #include "ncvalidate.h"
55 static const char *progname
;
59 #define vprint(args) printf args
65 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
66 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
68 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
71 static int gettimeofday(struct timeval
*tv
, struct timezone
*tz
)
73 struct __timeb32 time_info
;
75 if (NULL
== tv
) return -EFAULT
;
76 if (!_ftime32_s(&time_info
)) {
78 tv
->tv_sec
= time_info
.time
;
79 /* translate from milli to micro seconds */
80 tv
->tv_usec
= time_info
.millitm
* 1000;
91 void fatal(const char *fmt
, ...)
94 fprintf(stderr
, "%s: fatal error: ", progname
);
96 vfprintf(stderr
, fmt
, ap
);
102 int AnalyzeSections(ncfile
*ncf
, struct NCValidatorState
*vstate
) {
105 Elf32_Shdr
*shdr
= ncf
->sheaders
;
107 for (ii
= 0; ii
< ncf
->shnum
; ii
++) {
108 vprint(("section %d sh_addr %x offset %x flags %x\n",
109 ii
, (uint32_t)shdr
[ii
].sh_addr
,
110 (uint32_t)shdr
[ii
].sh_offset
, (uint32_t)shdr
[ii
].sh_flags
));
111 if ((shdr
[ii
].sh_flags
& SHF_EXECINSTR
) != SHF_EXECINSTR
)
113 vprint(("parsing section %d\n", ii
));
114 /* note we use NCDecodeSegment instead of NCValidateSegment */
115 /* because we don't want the check for a hlt at the end of */
116 /* the text segment as required by NaCl. */
117 NCDecodeSegment(ncf
->data
+ (shdr
[ii
].sh_addr
- ncf
->vbase
),
118 shdr
[ii
].sh_addr
, shdr
[ii
].sh_size
, vstate
);
124 static void AnalyzeCodeSegments(ncfile
*ncf
, const char *fname
) {
125 uint32_t vbase
, vlimit
;
126 struct NCValidatorState
*vstate
;
128 GetVBaseAndLimit(ncf
, &vbase
, &vlimit
);
129 vstate
= NCValidateInit(vbase
, vlimit
, ncf
->ncalign
);
130 if (AnalyzeSections(ncf
, vstate
) < 0) {
131 fprintf(stderr
, "%s: text validate failed\n", fname
);
133 if (NCValidateFinish(vstate
) != 0) {
134 vprint(("***MODULE %s IS UNSAFE***\n", fname
));
136 vprint(("***module %s is safe***\n", fname
));
138 Stats_Print(stdout
, vstate
);
139 NCValidateFreeState(&vstate
);
140 vprint(("Validated %s\n", fname
));
143 INLINE
double timeval2double(const struct timeval
*tv
) {
144 return ((double)tv
->tv_sec
+ ((double)tv
->tv_usec
)/1000000);
147 void PrintTimes(FILE *f
, const char *fname
,
150 struct timeval
*t2
) {
151 double dt0
, dt1
, dt2
;
152 dt0
= timeval2double(t0
);
153 dt1
= timeval2double(t1
);
154 dt2
= timeval2double(t2
);
156 fprintf(f
, "%s: %0.6f %0.6f\n", fname
, dt1
- dt0
, dt2
- dt1
);
159 int main(int argc
, const char *argv
[])
161 const char *loadname
= argv
[1];
162 struct timeval time0
, timel
, timev
;
166 if (loadname
== NULL
) {
167 extern void ncvalidate_unittests();
169 printf("no arguments given; running unit tests\n");
170 ncvalidate_unittests();
174 gettimeofday(&time0
, NULL
);
175 ncf
= nc_loadfile(loadname
);
177 fatal("nc_loadfile(%s): %s\n", loadname
, strerror(errno
));
179 gettimeofday(&timel
, NULL
);
180 AnalyzeCodeSegments(ncf
, loadname
);
181 gettimeofday(&timev
, NULL
);
183 PrintTimes(stderr
, loadname
, &time0
, &timel
, &timev
);