Skip to content

Commit 8565755

Browse files
committed
Auto merge of #1044 - faern:modern-alignment, r=alexcrichton
Add alignment feature and use #[repr(align(x))] Trying to solve #1042. Here I introduce the discussed feature that will allow going from struct alignment with a private `__align` field to using `#[repr(align(x))]`. However, I have not implemented it for all structs that require alignment yet, only `in6_addr`. This because I did not want to spend too much time before we have discussed and solved the remaining questions regarding this. One thing to discuss is testing. I have so far not done anything to the CI scripts. So currently they will still test the crate only with the `align` feature disabled. Thus they will make sure the `__align` fields are still correct. But no automatic tests make sure everything is correct when the `align` feature is turned on. What do we want to do about that? Can we insert another `cargo test` with `--features align` to make all the Travis jobs run the test suite twice, or will that slow things down too much? I have tried using this version of libc in rustc and the standard library. And successfully changed `Ipv6Addr::new` to not use any `unsafe` and to become a `const fn`. Whether or not we want that is out of scope for this PR, but my point was that the changes introduced with this PR allow much more flexible usage of the libc structs that have alignment.
2 parents 7d262c0 + e167a73 commit 8565755

26 files changed

+886
-515
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ appveyor = { repository = "rust-lang/libc", project_name = "rust-lang-libs/libc"
2020
[features]
2121
default = ["use_std"]
2222
use_std = []
23+
align = []
2324

2425
[workspace]
2526
members = ["libc-test"]

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ this via:
3535
libc = { version = "0.2", default-features = false }
3636
```
3737

38+
By default libc uses private fields in structs in order to enforce a certain
39+
memory alignment on them. These structs can be hard to instantiate outside of
40+
libc. To make libc use `#[repr(align(x))]`, instead of the private fields,
41+
activate the *align* feature. This requires Rust 1.25 or newer:
42+
43+
```toml
44+
[dependencies]
45+
libc = { version = "0.2", features = ["align"] }
46+
```
47+
3848
## What is libc?
3949

4050
The primary purpose of this crate is to provide all of the definitions necessary

ci/run.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ if [ "$QEMU" != "" ]; then
7979
exec grep "^PASSED .* tests" $CARGO_TARGET_DIR/out.log
8080
fi
8181

82-
# FIXME: x86_64-unknown-linux-gnux32 fail to compile wihout --release
82+
# FIXME: x86_64-unknown-linux-gnux32 fail to compile without --release
8383
# See https://github.com/rust-lang/rust/issues/45417
8484
opt=
8585
if [ "$TARGET" = "x86_64-unknown-linux-gnux32" ]; then
@@ -91,4 +91,8 @@ fi
9191
if [ "$TARGET" != "x86_64-rumprun-netbsd" ]; then
9292
cargo test $opt --no-default-features --manifest-path libc-test/Cargo.toml --target $TARGET
9393
fi
94+
# Test the #[repr(align(x))] feature if this is building on Rust >= 1.25
95+
if [ $(rustc --version | sed -E 's/^rustc 1\.([0-9]*)\..*/\1/') -ge 25 ]; then
96+
cargo test $opt --features align --manifest-path libc-test/Cargo.toml --target $TARGET
97+
fi
9498
exec cargo test $opt --manifest-path libc-test/Cargo.toml --target $TARGET

libc-test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ctest = { git = "https://github.com/alexcrichton/ctest" }
1414
[features]
1515
default = [ "use_std" ]
1616
use_std = [ "libc/use_std" ]
17+
align = [ "libc/align" ]
1718

1819
[[test]]
1920
name = "main"

src/fuchsia/mod.rs

Lines changed: 110 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,10 @@ s! {
166166
pub s_addr: in_addr_t,
167167
}
168168

169+
#[cfg_attr(feature = "align", repr(align(4)))]
169170
pub struct in6_addr {
170171
pub s6_addr: [u8; 16],
172+
#[cfg(not(feature = "align"))]
171173
__align: [u32; 0],
172174
}
173175

@@ -518,14 +520,30 @@ s! {
518520
pub ifa_data: *mut ::c_void
519521
}
520522

523+
#[cfg_attr(all(feature = "align",
524+
target_pointer_width = "32",
525+
any(target_arch = "mips",
526+
target_arch = "arm",
527+
target_arch = "powerpc",
528+
target_arch = "x86_64")),
529+
repr(align(4)))]
530+
#[cfg_attr(all(feature = "align",
531+
any(target_pointer_width = "64",
532+
not(any(target_arch = "mips",
533+
target_arch = "arm",
534+
target_arch = "powerpc",
535+
target_arch = "x86_64")))),
536+
repr(align(8)))]
521537
pub struct pthread_mutex_t {
522-
#[cfg(any(target_arch = "mips",
523-
target_arch = "arm",
524-
target_arch = "powerpc",
525-
all(target_arch = "x86_64",
526-
target_pointer_width = "32")))]
538+
#[cfg(all(not(feature = "align"),
539+
any(target_arch = "mips",
540+
target_arch = "arm",
541+
target_arch = "powerpc",
542+
all(target_arch = "x86_64",
543+
target_pointer_width = "32"))))]
527544
__align: [::c_long; 0],
528-
#[cfg(not(any(target_arch = "mips",
545+
#[cfg(not(any(feature = "align",
546+
target_arch = "mips",
529547
target_arch = "arm",
530548
target_arch = "powerpc",
531549
all(target_arch = "x86_64",
@@ -534,14 +552,30 @@ s! {
534552
size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
535553
}
536554

555+
#[cfg_attr(all(feature = "align",
556+
target_pointer_width = "32",
557+
any(target_arch = "mips",
558+
target_arch = "arm",
559+
target_arch = "powerpc",
560+
target_arch = "x86_64")),
561+
repr(align(4)))]
562+
#[cfg_attr(all(feature = "align",
563+
any(target_pointer_width = "64",
564+
not(any(target_arch = "mips",
565+
target_arch = "arm",
566+
target_arch = "powerpc",
567+
target_arch = "x86_64")))),
568+
repr(align(8)))]
537569
pub struct pthread_rwlock_t {
538-
#[cfg(any(target_arch = "mips",
539-
target_arch = "arm",
540-
target_arch = "powerpc",
541-
all(target_arch = "x86_64",
542-
target_pointer_width = "32")))]
570+
#[cfg(all(not(feature = "align"),
571+
any(target_arch = "mips",
572+
target_arch = "arm",
573+
target_arch = "powerpc",
574+
all(target_arch = "x86_64",
575+
target_pointer_width = "32"))))]
543576
__align: [::c_long; 0],
544-
#[cfg(not(any(target_arch = "mips",
577+
#[cfg(not(any(feature = "align",
578+
target_arch = "mips",
545579
target_arch = "arm",
546580
target_arch = "powerpc",
547581
all(target_arch = "x86_64",
@@ -550,39 +584,78 @@ s! {
550584
size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
551585
}
552586

587+
#[cfg_attr(all(feature = "align",
588+
any(target_pointer_width = "32",
589+
target_arch = "x86_64", target_arch = "powerpc64",
590+
target_arch = "mips64", target_arch = "s390x",
591+
target_arch = "sparc64",
592+
all(target_arch = "aarch64", target_env = "musl"))),
593+
repr(align(4)))]
594+
#[cfg_attr(all(feature = "align",
595+
not(any(target_pointer_width = "32",
596+
target_arch = "x86_64", target_arch = "powerpc64",
597+
target_arch = "mips64", target_arch = "s390x",
598+
target_arch = "sparc64",
599+
all(target_arch = "aarch64", target_env = "musl")))),
600+
repr(align(8)))]
553601
pub struct pthread_mutexattr_t {
554-
#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64",
555-
target_arch = "mips64", target_arch = "s390x",
556-
target_arch = "sparc64"))]
557-
__align: [::c_int; 0],
558-
#[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64",
602+
#[cfg(all(not(features = "align"),
603+
any(target_arch = "x86_64", target_arch = "powerpc64",
559604
target_arch = "mips64", target_arch = "s390x",
560-
target_arch = "sparc64", target_arch = "aarch64")))]
561-
__align: [::c_long; 0],
562-
#[cfg(all(target_arch = "aarch64", target_env = "gnu"))]
563-
__align: [::c_long; 0],
564-
#[cfg(all(target_arch = "aarch64", target_env = "musl"))]
605+
target_arch = "sparc64",
606+
all(target_arch = "aarch64", target_env = "musl"))))]
565607
__align: [::c_int; 0],
608+
#[cfg(all(not(features = "align"),
609+
not(any(target_arch = "x86_64", target_arch = "powerpc64",
610+
target_arch = "mips64", target_arch = "s390x",
611+
target_arch = "sparc64",
612+
all(target_arch = "aarch64", target_env = "musl")))))]
613+
__align: [::c_long; 0],
566614
size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
567615
}
568616

617+
#[cfg_attr(all(feature = "align",
618+
any(target_env = "musl", target_pointer_width = "32")),
619+
repr(align(4)))]
620+
#[cfg_attr(all(feature = "align",
621+
not(target_env = "musl"),
622+
target_pointer_width = "64"),
623+
repr(align(8)))]
569624
pub struct pthread_rwlockattr_t {
570-
#[cfg(any(target_env = "musl"))]
625+
#[cfg(all(not(feature = "align"), target_env = "musl"))]
571626
__align: [::c_int; 0],
572-
#[cfg(not(any(target_env = "musl")))]
627+
#[cfg(all(not(feature = "align"), not(target_env = "musl")))]
573628
__align: [::c_long; 0],
574629
size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T],
575630
}
576631

632+
#[cfg_attr(all(feature = "align",
633+
target_env = "musl",
634+
target_pointer_width = "32"),
635+
repr(align(4)))]
636+
#[cfg_attr(all(feature = "align",
637+
target_env = "musl",
638+
target_pointer_width = "64"),
639+
repr(align(8)))]
640+
#[cfg_attr(all(feature = "align",
641+
not(target_env = "musl"),
642+
target_arch = "x86"),
643+
repr(align(4)))]
644+
#[cfg_attr(all(feature = "align",
645+
not(target_env = "musl"),
646+
not(target_arch = "x86")),
647+
repr(align(8)))]
577648
pub struct pthread_cond_t {
578-
#[cfg(any(target_env = "musl"))]
649+
#[cfg(all(not(feature = "align"), target_env = "musl"))]
579650
__align: [*const ::c_void; 0],
580-
#[cfg(not(any(target_env = "musl")))]
651+
#[cfg(not(any(feature = "align", target_env = "musl")))]
581652
__align: [::c_longlong; 0],
582653
size: [u8; __SIZEOF_PTHREAD_COND_T],
583654
}
584655

656+
#[cfg_attr(feature = "align", repr(align(4)))]
585657
pub struct pthread_condattr_t {
658+
#[cfg(not(feature = "align"))]
586659
__align: [::c_int; 0],
587660
size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
588661
}
@@ -2004,18 +2077,17 @@ pub const RTLD_NOW: ::c_int = 0x2;
20042077

20052078
pub const TCP_MD5SIG: ::c_int = 14;
20062079

2007-
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
2008-
__align: [],
2009-
size: [0; __SIZEOF_PTHREAD_MUTEX_T],
2010-
};
2011-
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
2012-
__align: [],
2013-
size: [0; __SIZEOF_PTHREAD_COND_T],
2014-
};
2015-
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
2016-
__align: [],
2017-
size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
2018-
};
2080+
align_const! {
2081+
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
2082+
size: [0; __SIZEOF_PTHREAD_MUTEX_T],
2083+
};
2084+
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
2085+
size: [0; __SIZEOF_PTHREAD_COND_T],
2086+
};
2087+
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
2088+
size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
2089+
};
2090+
}
20192091
pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0;
20202092
pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1;
20212093
pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2;

src/macros.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,20 @@ macro_rules! f {
6969
macro_rules! __item {
7070
($i:item) => ($i)
7171
}
72+
73+
#[allow(unused_macros)]
74+
macro_rules! align_const {
75+
($($(#[$attr:meta])* pub const $name:ident : $t1:ty = $t2:ident { $($field:tt)* };)*) => ($(
76+
#[cfg(feature = "align")]
77+
$(#[$attr])*
78+
pub const $name : $t1 = $t2 {
79+
$($field)*
80+
};
81+
#[cfg(not(feature = "align"))]
82+
$(#[$attr])*
83+
pub const $name : $t1 = $t2 {
84+
$($field)*
85+
__align: [],
86+
};
87+
)*)
88+
}

src/redox/net.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ s! {
99
pub s_addr: in_addr_t,
1010
}
1111

12+
#[cfg_attr(feature = "align", repr(align(4)))]
1213
pub struct in6_addr {
1314
pub s6_addr: [u8; 16],
15+
#[cfg(not(feature = "align"))]
1416
__align: [u32; 0],
1517
}
1618

src/unix/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,10 @@ s! {
104104
pub s_addr: in_addr_t,
105105
}
106106

107+
#[cfg_attr(feature = "align", repr(align(4)))]
107108
pub struct in6_addr {
108109
pub s6_addr: [u8; 16],
110+
#[cfg(not(feature = "align"))]
109111
__align: [u32; 0],
110112
}
111113

0 commit comments

Comments
 (0)