1 : /*
2 : * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include "native_client/src/trusted/validator/x86/halt_trim.h"
8 :
9 : #include <stdio.h>
10 : #include "native_client/src/trusted/validator/x86/ncinstbuffer.h"
11 :
12 : /* Safety buffer size of halts we must keep, so that we guarantee
13 : * that we don't trim the last legal instruction in the
14 : * code segment. Note: we add 1 to the maximum instruction length just
15 : * to be safe.
16 : */
17 : static const NaClMemorySize kMinHaltKeepLength = MAX_INST_LENGTH + 1;
18 :
19 : /* x86 HALT opcode */
20 : static const uint8_t kNaClHalt = 0xf4;
21 :
22 : NaClMemorySize NCHaltTrimSize(uint8_t *mbase, NaClMemorySize sz,
23 179 : uint8_t alignment) {
24 : NaClMemorySize i;
25 : NaClMemorySize num_halts;
26 86963 : for (i = sz - 1; i > 0; --i) {
27 86955 : if (kNaClHalt != mbase[i]) break;
28 : }
29 179 : num_halts = sz - (i + 1);
30 179 : if (num_halts > kMinHaltKeepLength) {
31 : /* May be able to trim off trailing halts. */
32 : NaClMemorySize new_size;
33 : NaClMemorySize block_overflow;
34 16 : new_size = (sz - num_halts) + kMinHaltKeepLength;
35 : /* Round to nearest block alignment. */
36 16 : block_overflow = new_size % alignment;
37 16 : if (block_overflow) {
38 16 : new_size = new_size - block_overflow + alignment;
39 : }
40 : /* Never increase the segment size. */
41 16 : if (new_size < sz) {
42 7 : return new_size;
43 : }
44 : }
45 : /* No trim performed. */
46 172 : return sz;
47 : }
|