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 574 : NaClMemorySize NCHaltTrimSize(uint8_t *mbase, NaClMemorySize sz,
23 574 : uint8_t alignment) {
24 574 : NaClMemorySize i;
25 574 : NaClMemorySize num_halts;
26 2254 : for (i = sz - 1; i > 0; --i) {
27 1637 : if (kNaClHalt != mbase[i]) break;
28 553 : }
29 574 : num_halts = sz - (i + 1);
30 574 : if (num_halts > kMinHaltKeepLength) {
31 : /* May be able to trim off trailing halts. */
32 7 : NaClMemorySize new_size;
33 7 : NaClMemorySize block_overflow;
34 7 : new_size = (sz - num_halts) + kMinHaltKeepLength;
35 : /* Round to nearest block alignment. */
36 7 : block_overflow = new_size % alignment;
37 7 : if (block_overflow) {
38 7 : new_size = new_size - block_overflow + alignment;
39 7 : }
40 : /* Never increase the segment size. */
41 7 : if (new_size < sz) {
42 6 : return new_size;
43 : }
44 1 : }
45 : /* No trim performed. */
46 568 : return sz;
47 574 : }
|