OSDN Git Service

runtime: Better detection of memory allocation request overflow.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-make-slice.c
1 /* go-make-slice.c -- make a slice.
2
3    Copyright 2011 The Go Authors. All rights reserved.
4    Use of this source code is governed by a BSD-style
5    license that can be found in the LICENSE file.  */
6
7 #include <stdint.h>
8
9 #include "go-alloc.h"
10 #include "go-assert.h"
11 #include "go-panic.h"
12 #include "go-type.h"
13 #include "array.h"
14 #include "runtime.h"
15 #include "arch.h"
16 #include "malloc.h"
17
18 struct __go_open_array
19 __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len,
20                   uintptr_t cap)
21 {
22   const struct __go_slice_type* std;
23   int ilen;
24   int icap;
25   uintptr_t size;
26   struct __go_open_array ret;
27   unsigned int flag;
28
29   __go_assert (td->__code == GO_SLICE);
30   std = (const struct __go_slice_type *) td;
31
32   ilen = (int) len;
33   if (ilen < 0 || (uintptr_t) ilen != len)
34     runtime_panicstring ("makeslice: len out of range");
35
36   icap = (int) cap;
37   if (cap < len
38       || (uintptr_t) icap != cap
39       || (std->__element_type->__size > 0
40           && cap > MaxMem / std->__element_type->__size))
41     runtime_panicstring ("makeslice: cap out of range");
42
43   ret.__count = ilen;
44   ret.__capacity = icap;
45
46   size = cap * std->__element_type->__size;
47   flag = ((std->__element_type->__code & GO_NO_POINTERS) != 0
48           ? FlagNoPointers
49           : 0);
50   ret.__values = runtime_mallocgc (size, flag, 1, 1);
51
52   return ret;
53 }
54
55 struct __go_open_array
56 __go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len)
57 {
58   return __go_make_slice2 (td, len, len);
59 }
60
61 struct __go_open_array
62 __go_make_slice2_big (const struct __go_type_descriptor *td, uint64_t len,
63                       uint64_t cap)
64 {
65   uintptr_t slen;
66   uintptr_t scap;
67
68   slen = (uintptr_t) len;
69   if ((uint64_t) slen != len)
70     runtime_panicstring ("makeslice: len out of range");
71
72   scap = (uintptr_t) cap;
73   if ((uint64_t) scap != cap)
74     runtime_panicstring ("makeslice: cap out of range");
75
76   return __go_make_slice2 (td, slen, scap);
77 }
78
79 struct __go_open_array
80 __go_make_slice1_big (const struct __go_type_descriptor *td, uint64_t len)
81 {
82   return __go_make_slice2_big (td, len, len);
83 }