Skip to content

Commit 43cc32f

Browse files
committed
Merge branch 'master' into drop
2 parents aec5330 + 9653f79 commit 43cc32f

File tree

3,017 files changed

+7140
-3253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,017 files changed

+7140
-3253
lines changed

Diff for: RELEASES.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
Version 1.29.1 (2018-09-25)
2+
===========================
3+
4+
Security Notes
5+
--------------
6+
7+
- The standard library's `str::repeat` function contained an out of bounds write
8+
caused by an integer overflow. This has been fixed by deterministically
9+
panicking when an overflow happens.
10+
11+
Thank you to Scott McMurray for responsibily disclosing this vulnerability to
12+
us.
13+
114
Version 1.29.0 (2018-09-13)
215
==========================
316

Diff for: src/Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ dependencies = [
344344
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
345345
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
346346
"serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
347+
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
347348
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
348349
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
349350
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2372,6 +2373,7 @@ dependencies = [
23722373
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
23732374
"rustc 0.0.0",
23742375
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
2376+
"rustc_codegen_utils 0.0.0",
23752377
"rustc_data_structures 0.0.0",
23762378
"rustc_target 0.0.0",
23772379
"rustc_typeck 0.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# `emit-stack-sizes`
2+
3+
The tracking issue for this feature is: [#54192]
4+
5+
[#54192]: https://github.com/rust-lang/rust/issues/54192
6+
7+
------------------------
8+
9+
The rustc flag `-Z emit-stack-sizes` makes LLVM emit stack size metadata.
10+
11+
> **NOTE**: This LLVM feature only supports the ELF object format as of LLVM
12+
> 8.0. Using this flag with targets that use other object formats (e.g. macOS
13+
> and Windows) will result in it being ignored.
14+
15+
Consider this crate:
16+
17+
```
18+
#![crate_type = "lib"]
19+
20+
use std::ptr;
21+
22+
pub fn foo() {
23+
// this function doesn't use the stack
24+
}
25+
26+
pub fn bar() {
27+
let xs = [0u32; 2];
28+
29+
// force LLVM to allocate `xs` on the stack
30+
unsafe { ptr::read_volatile(&xs.as_ptr()); }
31+
}
32+
```
33+
34+
Using the `-Z emit-stack-sizes` flag produces extra linker sections in the
35+
output *object file*.
36+
37+
``` console
38+
$ rustc -C opt-level=3 --emit=obj foo.rs
39+
40+
$ size -A foo.o
41+
foo.o :
42+
section size addr
43+
.text 0 0
44+
.text._ZN3foo3foo17he211d7b4a3a0c16eE 1 0
45+
.text._ZN3foo3bar17h1acb594305f70c2eE 22 0
46+
.note.GNU-stack 0 0
47+
.eh_frame 72 0
48+
Total 95
49+
50+
$ rustc -C opt-level=3 --emit=obj -Z emit-stack-sizes foo.rs
51+
52+
$ size -A foo.o
53+
foo.o :
54+
section size addr
55+
.text 0 0
56+
.text._ZN3foo3foo17he211d7b4a3a0c16eE 1 0
57+
.stack_sizes 9 0
58+
.text._ZN3foo3bar17h1acb594305f70c2eE 22 0
59+
.stack_sizes 9 0
60+
.note.GNU-stack 0 0
61+
.eh_frame 72 0
62+
Total 113
63+
```
64+
65+
As of LLVM 7.0 the data will be written into a section named `.stack_sizes` and
66+
the format is "an array of pairs of function symbol values (pointer size) and
67+
stack sizes (unsigned LEB128)".
68+
69+
``` console
70+
$ objdump -d foo.o
71+
72+
foo.o: file format elf64-x86-64
73+
74+
Disassembly of section .text._ZN3foo3foo17he211d7b4a3a0c16eE:
75+
76+
0000000000000000 <_ZN3foo3foo17he211d7b4a3a0c16eE>:
77+
0: c3 retq
78+
79+
Disassembly of section .text._ZN3foo3bar17h1acb594305f70c2eE:
80+
81+
0000000000000000 <_ZN3foo3bar17h1acb594305f70c2eE>:
82+
0: 48 83 ec 10 sub $0x10,%rsp
83+
4: 48 8d 44 24 08 lea 0x8(%rsp),%rax
84+
9: 48 89 04 24 mov %rax,(%rsp)
85+
d: 48 8b 04 24 mov (%rsp),%rax
86+
11: 48 83 c4 10 add $0x10,%rsp
87+
15: c3 retq
88+
89+
$ objdump -s -j .stack_sizes foo.o
90+
91+
foo.o: file format elf64-x86-64
92+
93+
Contents of section .stack_sizes:
94+
0000 00000000 00000000 00 .........
95+
Contents of section .stack_sizes:
96+
0000 00000000 00000000 10 .........
97+
```
98+
99+
It's important to note that linkers will discard this linker section by default.
100+
To preserve the section you can use a linker script like the one shown below.
101+
102+
``` text
103+
/* file: keep-stack-sizes.x */
104+
SECTIONS
105+
{
106+
/* `INFO` makes the section not allocatable so it won't be loaded into memory */
107+
.stack_sizes (INFO) :
108+
{
109+
KEEP(*(.stack_sizes));
110+
}
111+
}
112+
```
113+
114+
The linker script must be passed to the linker using a rustc flag like `-C
115+
link-arg`.
116+
117+
```
118+
// file: src/main.rs
119+
use std::ptr;
120+
121+
#[inline(never)]
122+
fn main() {
123+
let xs = [0u32; 2];
124+
125+
// force LLVM to allocate `xs` on the stack
126+
unsafe { ptr::read_volatile(&xs.as_ptr()); }
127+
}
128+
```
129+
130+
``` console
131+
$ RUSTFLAGS="-Z emit-stack-sizes" cargo build --release
132+
133+
$ size -A target/release/hello | grep stack_sizes || echo section was not found
134+
section was not found
135+
136+
$ RUSTFLAGS="-Z emit-stack-sizes" cargo rustc --release -- \
137+
-C link-arg=-Wl,-Tkeep-stack-sizes.x \
138+
-C link-arg=-N
139+
140+
$ size -A target/release/hello | grep stack_sizes
141+
.stack_sizes 90 176272
142+
143+
$ # non-allocatable section (flags don't contain the "A" (alloc) flag)
144+
$ readelf -S target/release/hello
145+
Section Headers:
146+
[Nr] Name Type Address Offset
147+
Size EntSize Flags Link Info Align
148+
(..)
149+
[1031] .stack_sizes PROGBITS 000000000002b090 0002b0f0
150+
000000000000005a 0000000000000000 L 5 0 1
151+
152+
$ objdump -s -j .stack_sizes target/release/hello
153+
154+
target/release/hello: file format elf64-x86-64
155+
156+
Contents of section .stack_sizes:
157+
2b090 c0040000 00000000 08f00400 00000000 ................
158+
2b0a0 00080005 00000000 00000810 05000000 ................
159+
2b0b0 00000000 20050000 00000000 10400500 .... ........@..
160+
2b0c0 00000000 00087005 00000000 00000080 ......p.........
161+
2b0d0 05000000 00000000 90050000 00000000 ................
162+
2b0e0 00a00500 00000000 0000 ..........
163+
```
164+
165+
> Author note: I'm not entirely sure why, in *this* case, `-N` is required in
166+
> addition to `-Tkeep-stack-sizes.x`. For example, it's not required when
167+
> producing statically linked files for the ARM Cortex-M architecture.

Diff for: src/etc/gdb_rust_pretty_printing.py

+4-12
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,8 @@ def to_string(self):
322322
def children(self):
323323
(length, data_ptr) = \
324324
rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
325-
leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
326-
maybe_uninit_keys = leaf_node.get_child_at_index(3)
327-
manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
328-
keys = manually_drop_keys.get_child_at_index(0)
329-
gdb_ptr = keys.get_wrapped_value()
325+
val = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
326+
gdb_ptr = val.get_wrapped_value()
330327
for index in xrange(length):
331328
yield (str(index), gdb_ptr[index])
332329

@@ -348,14 +345,9 @@ def to_string(self):
348345
def children(self):
349346
(length, data_ptr) = \
350347
rustpp.extract_length_and_ptr_from_std_btreemap(self.__val)
351-
leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
352-
maybe_uninit_keys = leaf_node.get_child_at_index(3)
353-
manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
354-
keys = manually_drop_keys.get_child_at_index(0)
348+
keys = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
355349
keys_ptr = keys.get_wrapped_value()
356-
maybe_uninit_vals = leaf_node.get_child_at_index(4)
357-
manually_drop_vals = maybe_uninit_vals.get_child_at_index(1)
358-
vals = manually_drop_vals.get_child_at_index(0)
350+
vals = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(4)
359351
vals_ptr = vals.get_wrapped_value()
360352
for index in xrange(length):
361353
yield (str(index), keys_ptr[index])

Diff for: src/liballoc/collections/btree/node.rs

+20-20
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
// This implies that even an empty internal node has at least one edge.
4343

4444
use core::marker::PhantomData;
45-
use core::mem::{self, MaybeUninit};
45+
use core::mem;
4646
use core::ptr::{self, Unique, NonNull};
4747
use core::slice;
4848

@@ -73,7 +73,7 @@ struct LeafNode<K, V> {
7373
/// This node's index into the parent node's `edges` array.
7474
/// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
7575
/// This is only guaranteed to be initialized when `parent` is nonnull.
76-
parent_idx: MaybeUninit<u16>,
76+
parent_idx: u16,
7777

7878
/// The number of keys and values this node stores.
7979
///
@@ -83,8 +83,8 @@ struct LeafNode<K, V> {
8383

8484
/// The arrays storing the actual data of the node. Only the first `len` elements of each
8585
/// array are initialized and valid.
86-
keys: MaybeUninit<[K; CAPACITY]>,
87-
vals: MaybeUninit<[V; CAPACITY]>,
86+
keys: [K; CAPACITY],
87+
vals: [V; CAPACITY],
8888
}
8989

9090
impl<K, V> LeafNode<K, V> {
@@ -94,10 +94,10 @@ impl<K, V> LeafNode<K, V> {
9494
LeafNode {
9595
// As a general policy, we leave fields uninitialized if they can be, as this should
9696
// be both slightly faster and easier to track in Valgrind.
97-
keys: MaybeUninit::uninitialized(),
98-
vals: MaybeUninit::uninitialized(),
97+
keys: mem::uninitialized(),
98+
vals: mem::uninitialized(),
9999
parent: ptr::null(),
100-
parent_idx: MaybeUninit::uninitialized(),
100+
parent_idx: mem::uninitialized(),
101101
len: 0
102102
}
103103
}
@@ -115,10 +115,10 @@ unsafe impl Sync for LeafNode<(), ()> {}
115115
// ever take a pointer past the first key.
116116
static EMPTY_ROOT_NODE: LeafNode<(), ()> = LeafNode {
117117
parent: ptr::null(),
118-
parent_idx: MaybeUninit::uninitialized(),
118+
parent_idx: 0,
119119
len: 0,
120-
keys: MaybeUninit::uninitialized(),
121-
vals: MaybeUninit::uninitialized(),
120+
keys: [(); CAPACITY],
121+
vals: [(); CAPACITY],
122122
};
123123

124124
/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
@@ -430,7 +430,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
430430
root: self.root,
431431
_marker: PhantomData
432432
},
433-
idx: unsafe { usize::from(*self.as_leaf().parent_idx.get_ref()) },
433+
idx: self.as_leaf().parent_idx as usize,
434434
_marker: PhantomData
435435
})
436436
} else {
@@ -567,7 +567,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
567567
// the node, which is allowed by LLVM.
568568
unsafe {
569569
slice::from_raw_parts(
570-
self.as_leaf().keys.as_ptr() as *const K,
570+
self.as_leaf().keys.as_ptr(),
571571
self.len()
572572
)
573573
}
@@ -578,7 +578,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
578578
debug_assert!(!self.is_shared_root());
579579
unsafe {
580580
slice::from_raw_parts(
581-
self.as_leaf().vals.as_ptr() as *const V,
581+
self.as_leaf().vals.as_ptr(),
582582
self.len()
583583
)
584584
}
@@ -605,7 +605,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
605605
} else {
606606
unsafe {
607607
slice::from_raw_parts_mut(
608-
self.as_leaf_mut().keys.get_mut() as *mut [K] as *mut K,
608+
&mut self.as_leaf_mut().keys as *mut [K] as *mut K,
609609
self.len()
610610
)
611611
}
@@ -616,7 +616,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
616616
debug_assert!(!self.is_shared_root());
617617
unsafe {
618618
slice::from_raw_parts_mut(
619-
self.as_leaf_mut().vals.get_mut() as *mut [V] as *mut V,
619+
&mut self.as_leaf_mut().vals as *mut [V] as *mut V,
620620
self.len()
621621
)
622622
}
@@ -1013,7 +1013,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
10131013
let ptr = self.node.as_internal_mut() as *mut _;
10141014
let mut child = self.descend();
10151015
child.as_leaf_mut().parent = ptr;
1016-
child.as_leaf_mut().parent_idx.set(idx);
1016+
child.as_leaf_mut().parent_idx = idx;
10171017
}
10181018

10191019
/// Unsafely asserts to the compiler some static information about whether the underlying
@@ -1152,12 +1152,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
11521152

11531153
ptr::copy_nonoverlapping(
11541154
self.node.keys().as_ptr().add(self.idx + 1),
1155-
new_node.keys.as_mut_ptr() as *mut K,
1155+
new_node.keys.as_mut_ptr(),
11561156
new_len
11571157
);
11581158
ptr::copy_nonoverlapping(
11591159
self.node.vals().as_ptr().add(self.idx + 1),
1160-
new_node.vals.as_mut_ptr() as *mut V,
1160+
new_node.vals.as_mut_ptr(),
11611161
new_len
11621162
);
11631163

@@ -1210,12 +1210,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
12101210

12111211
ptr::copy_nonoverlapping(
12121212
self.node.keys().as_ptr().add(self.idx + 1),
1213-
new_node.data.keys.as_mut_ptr() as *mut K,
1213+
new_node.data.keys.as_mut_ptr(),
12141214
new_len
12151215
);
12161216
ptr::copy_nonoverlapping(
12171217
self.node.vals().as_ptr().add(self.idx + 1),
1218-
new_node.data.vals.as_mut_ptr() as *mut V,
1218+
new_node.data.vals.as_mut_ptr(),
12191219
new_len
12201220
);
12211221
ptr::copy_nonoverlapping(

Diff for: src/liballoc/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@
120120
#![feature(rustc_const_unstable)]
121121
#![feature(const_vec_new)]
122122
#![feature(slice_partition_dedup)]
123-
#![feature(maybe_uninit)]
124123

125124
// Allow testing this library
126125

0 commit comments

Comments
 (0)