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