Compare commits
574 Commits
android-5.
...
l-preview
Author | SHA1 | Date | |
---|---|---|---|
![]() |
dec4de456c | ||
![]() |
4a9e1937c5 | ||
![]() |
5281e1fb15 | ||
![]() |
90aa7e374f | ||
![]() |
8bb12127e6 | ||
![]() |
3ce0769aa5 | ||
![]() |
e91d9cd4ad | ||
![]() |
f5e0258268 | ||
![]() |
ea6eae182a | ||
![]() |
4544d9f9bf | ||
![]() |
71cbcdcf94 | ||
![]() |
a7c2e0bad6 | ||
![]() |
97df16ba5c | ||
![]() |
1816025684 | ||
![]() |
c229705051 | ||
![]() |
a6bee4df4c | ||
![]() |
083769a3df | ||
![]() |
fee09e556f | ||
![]() |
94571f9ade | ||
![]() |
90a29db0f4 | ||
![]() |
4c0862474e | ||
![]() |
472cce5c98 | ||
![]() |
8c3901b299 | ||
![]() |
efee1ce46a | ||
![]() |
2698f9ef84 | ||
![]() |
14538ca75e | ||
![]() |
62a665a605 | ||
![]() |
78ba823033 | ||
![]() |
8dd3b65f2d | ||
![]() |
488268b134 | ||
![]() |
e9c216fca5 | ||
![]() |
9afb2f2106 | ||
![]() |
d0944d9ed3 | ||
![]() |
f183f95946 | ||
![]() |
8a7f8387b3 | ||
![]() |
ca75f9cdeb | ||
![]() |
72d72d9126 | ||
![]() |
0c0e728bd8 | ||
![]() |
667853d477 | ||
![]() |
cfd8c45725 | ||
![]() |
ac3c94d031 | ||
![]() |
51166d3aa2 | ||
![]() |
0511534dcb | ||
![]() |
bfeef2d3a9 | ||
![]() |
75129ae9f3 | ||
![]() |
3ea4d56ed4 | ||
![]() |
1364101067 | ||
![]() |
b4b15c63a1 | ||
![]() |
5cc5c5ea0b | ||
![]() |
2fbb1b653e | ||
![]() |
5a3ca37458 | ||
![]() |
c9e4f2de0a | ||
![]() |
658727e111 | ||
![]() |
3d773274ad | ||
![]() |
e8d9057e30 | ||
![]() |
7d3f553f98 | ||
![]() |
eeb9aa02b7 | ||
![]() |
b0fd55608e | ||
![]() |
6d2dd6a740 | ||
![]() |
75d66dd9a7 | ||
![]() |
81fca35672 | ||
![]() |
6869d26ad9 | ||
![]() |
b5cba6081b | ||
![]() |
1aaa17802c | ||
![]() |
9969fecad2 | ||
![]() |
f4320e867c | ||
![]() |
f04a8bc226 | ||
![]() |
513e29e16f | ||
![]() |
6d569b9201 | ||
![]() |
07e5bc152d | ||
![]() |
a6eef3be10 | ||
![]() |
884a3de60f | ||
![]() |
558ec8103b | ||
![]() |
db6fea86a5 | ||
![]() |
b84f667e93 | ||
![]() |
9b543ffeac | ||
![]() |
ae97a776ea | ||
![]() |
48be71d02b | ||
![]() |
4ef0e59f33 | ||
![]() |
8d0b2dbf21 | ||
![]() |
d5df4124bb | ||
![]() |
2d111d9eb1 | ||
![]() |
b19bd93f8b | ||
![]() |
1b20dafdbe | ||
![]() |
cadccfd708 | ||
![]() |
89fd32362b | ||
![]() |
7d849ac378 | ||
![]() |
76ac4d0853 | ||
![]() |
81156d93c5 | ||
![]() |
0c8fb51e6b | ||
![]() |
f8896c6c93 | ||
![]() |
12e3f22c7c | ||
![]() |
252c1ac973 | ||
![]() |
701cf9419b | ||
![]() |
e04aa450c2 | ||
![]() |
31e072fc9b | ||
![]() |
ecf532fa1c | ||
![]() |
c4bcc75f09 | ||
![]() |
1f7d5ac538 | ||
![]() |
6cdeb5234d | ||
![]() |
0481471b1b | ||
![]() |
e49491ada4 | ||
![]() |
3a5aeba4bd | ||
![]() |
d9898c5b82 | ||
![]() |
9997daa0ff | ||
![]() |
b104be321f | ||
![]() |
b0c0037370 | ||
![]() |
85a932c0c9 | ||
![]() |
c8bd2abab2 | ||
![]() |
96bc37f2e1 | ||
![]() |
73e6c9b393 | ||
![]() |
188d093993 | ||
![]() |
7ca5c4b99b | ||
![]() |
98ab0c52f5 | ||
![]() |
d644fecc8e | ||
![]() |
e93be99da0 | ||
![]() |
690211fcf8 | ||
![]() |
a4ed64d4c3 | ||
![]() |
aa66e88280 | ||
![]() |
8cf61dab5f | ||
![]() |
852d4fbbe9 | ||
![]() |
055a59c3ed | ||
![]() |
17e7d3208c | ||
![]() |
abefc93ff3 | ||
![]() |
a864e72b56 | ||
![]() |
528ad742c6 | ||
![]() |
567d3fcb7e | ||
![]() |
4fcfd3a474 | ||
![]() |
af12924f67 | ||
![]() |
5a69da8d7a | ||
![]() |
f05410edc6 | ||
![]() |
c08c25b4c9 | ||
![]() |
21db6ff108 | ||
![]() |
4a6e71100e | ||
![]() |
c2d39088d8 | ||
![]() |
9a05e3818a | ||
![]() |
fc5a93f7a2 | ||
![]() |
ebf37e3886 | ||
![]() |
04643c181c | ||
![]() |
a71b4c3f14 | ||
![]() |
c57e5c8289 | ||
![]() |
2169e17482 | ||
![]() |
31165edf57 | ||
![]() |
3c5037f1b3 | ||
![]() |
87b6906f6e | ||
![]() |
b05ec5ae93 | ||
![]() |
8642165344 | ||
![]() |
0ab5fd9a5a | ||
![]() |
49eed7db79 | ||
![]() |
08dc9d83a2 | ||
![]() |
93951cfa96 | ||
![]() |
0dc39f9952 | ||
![]() |
e8a95624b6 | ||
![]() |
34c987a6dd | ||
![]() |
b2da456253 | ||
![]() |
a186b2e0ca | ||
![]() |
d9cb0ed281 | ||
![]() |
60452a211c | ||
![]() |
9f423c554a | ||
![]() |
c296e4f151 | ||
![]() |
413de5b0d4 | ||
![]() |
04303f5a8a | ||
![]() |
e716044918 | ||
![]() |
6fe376d392 | ||
![]() |
adc01348ee | ||
![]() |
8e4d371091 | ||
![]() |
13d6023aac | ||
![]() |
d5e1c583a6 | ||
![]() |
fb8d60f743 | ||
![]() |
653676dde8 | ||
![]() |
755318548d | ||
![]() |
82e71085c2 | ||
![]() |
90be6c5fc5 | ||
![]() |
6ced005123 | ||
![]() |
bee1993a14 | ||
![]() |
0bd28a43da | ||
![]() |
ba8d4f460b | ||
![]() |
6a310f4ad6 | ||
![]() |
1b77423eff | ||
![]() |
77784cb9b7 | ||
![]() |
bf50e2645d | ||
![]() |
03fef1f511 | ||
![]() |
2ad11a96a1 | ||
![]() |
2f5cf100a8 | ||
![]() |
e2d86feb7b | ||
![]() |
3ec67de051 | ||
![]() |
36a5aa057c | ||
![]() |
56433ee2a2 | ||
![]() |
e7c9a387fa | ||
![]() |
f240aa8089 | ||
![]() |
34ac60ca16 | ||
![]() |
7c02d9428c | ||
![]() |
4a6e9a835a | ||
![]() |
17cc8e539a | ||
![]() |
b1a6c319c4 | ||
![]() |
1cff9a8964 | ||
![]() |
aea393c096 | ||
![]() |
8f61d99183 | ||
![]() |
380a3be757 | ||
![]() |
148dff3ec6 | ||
![]() |
370704d69d | ||
![]() |
837a962bf5 | ||
![]() |
5cba3c6f8e | ||
![]() |
2997ae83d5 | ||
![]() |
e8ba50fe0d | ||
![]() |
0b8f6d592a | ||
![]() |
36f451a6d9 | ||
![]() |
eb27bbae8f | ||
![]() |
95b0c6a940 | ||
![]() |
2c58104718 | ||
![]() |
2214a1ce17 | ||
![]() |
85ef3b5b80 | ||
![]() |
ae51accf22 | ||
![]() |
5c2264a136 | ||
![]() |
5681fe8eae | ||
![]() |
26a8eb50a8 | ||
![]() |
73d2059f9b | ||
![]() |
f83c208b82 | ||
![]() |
21451f5bf6 | ||
![]() |
c729d4f237 | ||
![]() |
a40a16eab1 | ||
![]() |
8fb639ca91 | ||
![]() |
69c2d7dc64 | ||
![]() |
460ad7454a | ||
![]() |
e39e47c6b3 | ||
![]() |
0f001b67fe | ||
![]() |
d74aa58035 | ||
![]() |
aad92067bf | ||
![]() |
66bbf1595c | ||
![]() |
6abf624d12 | ||
![]() |
a6ac54a215 | ||
![]() |
8d8a789c49 | ||
![]() |
5f35710fad | ||
![]() |
6487f0d834 | ||
![]() |
9aea164457 | ||
![]() |
5920a9ad5f | ||
![]() |
a4831cb4a3 | ||
![]() |
ea66004c4a | ||
![]() |
9990b3973b | ||
![]() |
33df10f284 | ||
![]() |
b587f339db | ||
![]() |
c71483c0b3 | ||
![]() |
bce18c9163 | ||
![]() |
d9ff722661 | ||
![]() |
3c3624f3df | ||
![]() |
671f96cd44 | ||
![]() |
011e111d29 | ||
![]() |
201f36d23b | ||
![]() |
cf5fc80c3e | ||
![]() |
14669a939d | ||
![]() |
d3d89f0d28 | ||
![]() |
fc829736e1 | ||
![]() |
b4673c4102 | ||
![]() |
f903558446 | ||
![]() |
e07b4da53d | ||
![]() |
320a01d516 | ||
![]() |
498eb18b82 | ||
![]() |
f9e147b0bf | ||
![]() |
b3ebfecdae | ||
![]() |
b2a30ee8d2 | ||
![]() |
8adace5f2c | ||
![]() |
b58db8b083 | ||
![]() |
001815ed19 | ||
![]() |
7b956ede3f | ||
![]() |
aca9cae309 | ||
![]() |
27a9aed819 | ||
![]() |
c74a7680a4 | ||
![]() |
aa13e839f0 | ||
![]() |
44352f5f7f | ||
![]() |
c0cd9ce5df | ||
![]() |
4b41555ba5 | ||
![]() |
f0d8970435 | ||
![]() |
05f0bfd6c5 | ||
![]() |
afe58ad989 | ||
![]() |
4ee7c325df | ||
![]() |
356a6249d8 | ||
![]() |
071bed8091 | ||
![]() |
fc8974b7aa | ||
![]() |
1737b15937 | ||
![]() |
8f3b8f523e | ||
![]() |
58bb54c38b | ||
![]() |
5c1a7fdbd5 | ||
![]() |
5dea47221a | ||
![]() |
450aaa018d | ||
![]() |
e880c736d6 | ||
![]() |
8da304b997 | ||
![]() |
a3ad450a2e | ||
![]() |
28f1770101 | ||
![]() |
69fb9f3f40 | ||
![]() |
3b10ba6f1b | ||
![]() |
319356e39c | ||
![]() |
c7de919129 | ||
![]() |
6676a7d4ee | ||
![]() |
847e52b9b7 | ||
![]() |
1d53ae2a01 | ||
![]() |
ec95a9cf11 | ||
![]() |
296895f1a9 | ||
![]() |
86f594b19b | ||
![]() |
29bbc9dd4c | ||
![]() |
4625dd751e | ||
![]() |
e057b9fc82 | ||
![]() |
4cafa3ce80 | ||
![]() |
9685c30a23 | ||
![]() |
a492605849 | ||
![]() |
0cd83ebb0e | ||
![]() |
5120bcf9f1 | ||
![]() |
c2048944ff | ||
![]() |
11387985d2 | ||
![]() |
e505cc66a6 | ||
![]() |
4bea498544 | ||
![]() |
32429606bf | ||
![]() |
bbe06e0da1 | ||
![]() |
e0c56efddf | ||
![]() |
83b637fa28 | ||
![]() |
851135bf99 | ||
![]() |
1f39afc8d4 | ||
![]() |
cc4259ed92 | ||
![]() |
f6824b26ae | ||
![]() |
29f06943a1 | ||
![]() |
416d7ddaff | ||
![]() |
b6b5cb5389 | ||
![]() |
f4e721dd51 | ||
![]() |
af9da4a343 | ||
![]() |
fbe9d3dfeb | ||
![]() |
052fa3a34c | ||
![]() |
15b914c8f3 | ||
![]() |
4f8268e38f | ||
![]() |
9e4ffa7032 | ||
![]() |
857fa6b2a3 | ||
![]() |
34da32e7dd | ||
![]() |
6ecd1cd195 | ||
![]() |
a2c6ae6f84 | ||
![]() |
b78e60e7b7 | ||
![]() |
cb322a1168 | ||
![]() |
a40fdbd565 | ||
![]() |
64ae11ab76 | ||
![]() |
cc7e5f489f | ||
![]() |
6bfcefe02f | ||
![]() |
07401c7136 | ||
![]() |
e5055179fd | ||
![]() |
f1e64b5c17 | ||
![]() |
f73183f1a3 | ||
![]() |
7b87d441b0 | ||
![]() |
59de803af9 | ||
![]() |
9f5dee55aa | ||
![]() |
3e4a0099a1 | ||
![]() |
c674edbf27 | ||
![]() |
608217e167 | ||
![]() |
d2bd3c4717 | ||
![]() |
14241402de | ||
![]() |
c764fb24cc | ||
![]() |
57b7a6110e | ||
![]() |
9e307af982 | ||
![]() |
ae558d6b4b | ||
![]() |
a4a8c4feb8 | ||
![]() |
00aaea3645 | ||
![]() |
9d34f6a909 | ||
![]() |
0d15094287 | ||
![]() |
0b9fa4c9bf | ||
![]() |
ef619cc083 | ||
![]() |
4756afe3d5 | ||
![]() |
4caa1f0977 | ||
![]() |
538db6d2e6 | ||
![]() |
2b3b2ecee8 | ||
![]() |
2e6c5fc4e9 | ||
![]() |
2bd88d450e | ||
![]() |
9598b8c415 | ||
![]() |
47793d6a29 | ||
![]() |
3157211849 | ||
![]() |
2320b02c7d | ||
![]() |
d5fbc37119 | ||
![]() |
6b841db2ba | ||
![]() |
b6ed54076a | ||
![]() |
0e7f8a9e52 | ||
![]() |
7134fc3089 | ||
![]() |
c4a1de1ae2 | ||
![]() |
3bcd414b78 | ||
![]() |
dc1fb7000a | ||
![]() |
55244a9bdb | ||
![]() |
2b021e1066 | ||
![]() |
b61c50647b | ||
![]() |
1e8587a479 | ||
![]() |
c5d6df6f2f | ||
![]() |
35d226e05d | ||
![]() |
b9d674c8ad | ||
![]() |
09c39d6df0 | ||
![]() |
6f4220c49e | ||
![]() |
f4c948a9e9 | ||
![]() |
17f83c93cb | ||
![]() |
f800969d35 | ||
![]() |
e4fcc3ad2b | ||
![]() |
b810462028 | ||
![]() |
8a76ee821e | ||
![]() |
02aa70589d | ||
![]() |
2222eae61e | ||
![]() |
3a25ab952b | ||
![]() |
934c8015d5 | ||
![]() |
ce6b1abbb1 | ||
![]() |
54d24e099c | ||
![]() |
6d40d34908 | ||
![]() |
5d9e145c62 | ||
![]() |
3c7c9a8d3f | ||
![]() |
db2e0247ed | ||
![]() |
fd5ee9aebc | ||
![]() |
0baf2ca34c | ||
![]() |
5f5cc45cf0 | ||
![]() |
205cc41556 | ||
![]() |
2cfb4e8e2e | ||
![]() |
2b6cdb5e45 | ||
![]() |
4571f31bd4 | ||
![]() |
7d05f741e7 | ||
![]() |
019d395811 | ||
![]() |
1467dfe3e8 | ||
![]() |
d0cce14364 | ||
![]() |
891ec7a6e4 | ||
![]() |
8457779b34 | ||
![]() |
ad5e8b5073 | ||
![]() |
0d4ccee351 | ||
![]() |
224ff048ef | ||
![]() |
104a472958 | ||
![]() |
76212eeb53 | ||
![]() |
9a74e4c15c | ||
![]() |
b3aaf398e1 | ||
![]() |
4f85c6ffd3 | ||
![]() |
1f4c536fd5 | ||
![]() |
f2c1e7ee78 | ||
![]() |
db0785cbf9 | ||
![]() |
042426ba63 | ||
![]() |
6e3823d37e | ||
![]() |
edd81faff0 | ||
![]() |
e942b3ed81 | ||
![]() |
00c16c1b92 | ||
![]() |
51a22a12ab | ||
![]() |
4d0f742afe | ||
![]() |
ca5b6a74a7 | ||
![]() |
30214b901e | ||
![]() |
c5a13efa9b | ||
![]() |
a0db464187 | ||
![]() |
bc9f9f25bf | ||
![]() |
3788a1ee8e | ||
![]() |
3726f9c38b | ||
![]() |
1c5e415f8c | ||
![]() |
88a1f520d2 | ||
![]() |
f2d8c357ee | ||
![]() |
651a0683ca | ||
![]() |
92f0c91b82 | ||
![]() |
01bd32e0e4 | ||
![]() |
d994622ebf | ||
![]() |
6b6364a7fc | ||
![]() |
cdd2f072af | ||
![]() |
512bc52326 | ||
![]() |
85ebcfceb6 | ||
![]() |
e380960813 | ||
![]() |
f3868fa735 | ||
![]() |
51fde5b865 | ||
![]() |
b4b7e0547d | ||
![]() |
13bab43337 | ||
![]() |
3a238ae762 | ||
![]() |
9d2a05a6dd | ||
![]() |
bb91a1b845 | ||
![]() |
28285f85a1 | ||
![]() |
8b91980e4c | ||
![]() |
1628eb1d43 | ||
![]() |
afc8672387 | ||
![]() |
df85f50b82 | ||
![]() |
de69069fcf | ||
![]() |
9eae8405e8 | ||
![]() |
a7ef8188e2 | ||
![]() |
6a918870ba | ||
![]() |
447fe1c23b | ||
![]() |
b6cc8e00cd | ||
![]() |
36bacd237d | ||
![]() |
1aec7c1a35 | ||
![]() |
0f7ed163cf | ||
![]() |
e03e1eac0b | ||
![]() |
4ad5066e1d | ||
![]() |
861c0ef37b | ||
![]() |
a7dc7600fe | ||
![]() |
4916706cfe | ||
![]() |
17886971ff | ||
![]() |
f4c1a36a45 | ||
![]() |
2b591b3742 | ||
![]() |
aa0f2bdbc2 | ||
![]() |
52f8271fa9 | ||
![]() |
a406ee6d5f | ||
![]() |
24dcda0f4f | ||
![]() |
ed48534718 | ||
![]() |
50a9630cc2 | ||
![]() |
905e6d58aa | ||
![]() |
a4c14fda91 | ||
![]() |
1abb8bd21d | ||
![]() |
83b9826e68 | ||
![]() |
79310994d2 | ||
![]() |
c7706a02ad | ||
![]() |
18a1bbe6e1 | ||
![]() |
40a5217448 | ||
![]() |
123172ae37 | ||
![]() |
f1837377d2 | ||
![]() |
dbf52ec37b | ||
![]() |
4151ea73b7 | ||
![]() |
d6f614a4e1 | ||
![]() |
3e424d0a24 | ||
![]() |
bc5a3ec6df | ||
![]() |
7d22a45196 | ||
![]() |
dd37251c47 | ||
![]() |
f965075749 | ||
![]() |
be0e43b776 | ||
![]() |
f9bfc2ff8e | ||
![]() |
afe6360627 | ||
![]() |
337c0cefdc | ||
![]() |
efe13832dc | ||
![]() |
8a2ecf868f | ||
![]() |
21972b61ec | ||
![]() |
1a918d9be8 | ||
![]() |
39d903aea9 | ||
![]() |
8c66fd798e | ||
![]() |
f1e83cc34a | ||
![]() |
8dbe3f0f51 | ||
![]() |
ba23bd0a40 | ||
![]() |
467e49be70 | ||
![]() |
5d2f86f363 | ||
![]() |
ea42a6caea | ||
![]() |
3758a244cf | ||
![]() |
e26ac7f776 | ||
![]() |
ca70453e84 | ||
![]() |
79b5a39617 | ||
![]() |
f541650828 | ||
![]() |
0f7d882bb7 | ||
![]() |
4d421901e5 | ||
![]() |
2b67d7dee0 | ||
![]() |
925d388e24 | ||
![]() |
3ad8ecb64e | ||
![]() |
b828eaeb45 | ||
![]() |
ee7f1b5946 | ||
![]() |
1fb90a8aa0 | ||
![]() |
6b55ba54ef | ||
![]() |
e9731387f4 | ||
![]() |
97e31dedf0 | ||
![]() |
7dd126a38c | ||
![]() |
9c07aee83b | ||
![]() |
3c2b71ad56 | ||
![]() |
6425327c32 | ||
![]() |
d18b87f38d | ||
![]() |
8a3d1ca183 | ||
![]() |
76282482db | ||
![]() |
9f165d24f0 | ||
![]() |
6bf42ddc79 | ||
![]() |
2f9c6e38b8 | ||
![]() |
169e2bf6bd | ||
![]() |
d7453860a6 | ||
![]() |
43363ab720 | ||
![]() |
8b002362d9 | ||
![]() |
94f84d36a9 | ||
![]() |
98b088dce7 | ||
![]() |
f13aa6fc5b | ||
![]() |
625993dfbb | ||
![]() |
770d0f6177 | ||
![]() |
53531ccebb | ||
![]() |
64035c4a4b | ||
![]() |
ea271fdf26 | ||
![]() |
52023cb725 | ||
![]() |
3fa60e10bc | ||
![]() |
51c914b7fd | ||
![]() |
27047faf28 | ||
![]() |
5656a0c494 | ||
![]() |
e612add051 | ||
![]() |
ee3608f9d3 | ||
![]() |
a167eef548 | ||
![]() |
673bff01ae | ||
![]() |
76c241b091 | ||
![]() |
4ae938698c | ||
![]() |
4f0b67a8db | ||
![]() |
91f2074e5f | ||
![]() |
53c3c271dc |
@@ -4,40 +4,52 @@ Working on bionic
|
||||
What are the big pieces of bionic?
|
||||
----------------------------------
|
||||
|
||||
libc/ --- libc.so, libc.a
|
||||
The C library. Stuff like fopen(3) and kill(2).
|
||||
libm/ --- libm.so, libm.a
|
||||
The math library. Traditionally Unix systems kept stuff like sin(3) and
|
||||
cos(3) in a separate library to save space in the days before shared
|
||||
libraries.
|
||||
libdl/ --- libdl.so
|
||||
The dynamic linker interface library. This is actually just a bunch of
|
||||
stubs that the dynamic linker replaces with pointers to its own
|
||||
implementation at runtime. This is where stuff like dlopen(3) lives.
|
||||
libstdc++/ --- libstdc++.so
|
||||
The C++ ABI support functions. The C++ compiler doesn't know how to
|
||||
implement thread-safe static initialization and the like, so it just calls
|
||||
functions that are supplied by the system. Stuff like __cxa_guard_acquire
|
||||
and __cxa_pure_virtual live here.
|
||||
#### libc/ --- libc.so, libc.a
|
||||
|
||||
linker/ --- /system/bin/linker and /system/bin/linker64
|
||||
The dynamic linker. When you run a dynamically-linked executable, its ELF
|
||||
file has a DT_INTERP entry that says "use the following program to start me".
|
||||
On Android, that's either linker or linker64 (depending on whether it's a
|
||||
32-bit or 64-bit executable). It's responsible for loading the ELF executable
|
||||
into memory and resolving references to symbols (so that when your code tries
|
||||
to jump to fopen(3), say, it lands in the right place).
|
||||
The C library. Stuff like `fopen(3)` and `kill(2)`.
|
||||
|
||||
tests/ --- unit tests
|
||||
The tests/ directory contains unit tests. Roughly arranged as one file per
|
||||
publicly-exported header file.
|
||||
benchmarks/ --- benchmarks
|
||||
The benchmarks/ directory contains benchmarks.
|
||||
#### libm/ --- libm.so, libm.a
|
||||
|
||||
The math library. Traditionally Unix systems kept stuff like `sin(3)` and
|
||||
`cos(3)` in a separate library to save space in the days before shared
|
||||
libraries.
|
||||
|
||||
#### libdl/ --- libdl.so
|
||||
|
||||
The dynamic linker interface library. This is actually just a bunch of stubs
|
||||
that the dynamic linker replaces with pointers to its own implementation at
|
||||
runtime. This is where stuff like `dlopen(3)` lives.
|
||||
|
||||
#### libstdc++/ --- libstdc++.so
|
||||
|
||||
The C++ ABI support functions. The C++ compiler doesn't know how to implement
|
||||
thread-safe static initialization and the like, so it just calls functions that
|
||||
are supplied by the system. Stuff like `__cxa_guard_acquire` and
|
||||
`__cxa_pure_virtual` live here.
|
||||
|
||||
#### linker/ --- /system/bin/linker and /system/bin/linker64
|
||||
|
||||
The dynamic linker. When you run a dynamically-linked executable, its ELF file
|
||||
has a `DT_INTERP` entry that says "use the following program to start me". On
|
||||
Android, that's either `linker` or `linker64` (depending on whether it's a
|
||||
32-bit or 64-bit executable). It's responsible for loading the ELF executable
|
||||
into memory and resolving references to symbols (so that when your code tries to
|
||||
jump to `fopen(3)`, say, it lands in the right place).
|
||||
|
||||
#### tests/ --- unit tests
|
||||
|
||||
The `tests/` directory contains unit tests. Roughly arranged as one file per
|
||||
publicly-exported header file.
|
||||
|
||||
#### benchmarks/ --- benchmarks
|
||||
|
||||
The `benchmarks/` directory contains benchmarks.
|
||||
|
||||
|
||||
What's in libc/?
|
||||
----------------
|
||||
|
||||
<pre>
|
||||
libc/
|
||||
arch-arm/
|
||||
arch-arm64/
|
||||
@@ -121,6 +133,7 @@ libc/
|
||||
zoneinfo/
|
||||
# Android-format time zone data.
|
||||
# See 'Updating tzdata' later.
|
||||
</pre>
|
||||
|
||||
|
||||
Adding system calls
|
||||
@@ -160,3 +173,74 @@ This is fully automated:
|
||||
|
||||
1. Run update-tzdata.py.
|
||||
|
||||
|
||||
Running the tests
|
||||
-----------------
|
||||
|
||||
The tests are all built from the tests/ directory.
|
||||
|
||||
### Device tests
|
||||
|
||||
$ mma
|
||||
$ adb sync
|
||||
$ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32
|
||||
$ adb shell \
|
||||
/data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static32
|
||||
# Only for 64-bit targets
|
||||
$ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64
|
||||
$ adb shell \
|
||||
/data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static64
|
||||
|
||||
### Host tests
|
||||
|
||||
The host tests require that you have `lunch`ed either an x86 or x86_64 target.
|
||||
|
||||
$ mma
|
||||
# 64-bit tests for 64-bit targets, 32-bit otherwise.
|
||||
$ mm bionic-unit-tests-run-on-host
|
||||
# Only exists for 64-bit targets.
|
||||
$ mm bionic-unit-tests-run-on-host32
|
||||
|
||||
### Against glibc
|
||||
|
||||
As a way to check that our tests do in fact test the correct behavior (and not
|
||||
just the behavior we think is correct), it is possible to run the tests against
|
||||
the host's glibc.
|
||||
|
||||
$ mma
|
||||
$ bionic-unit-tests-glibc32 # already in your path
|
||||
$ bionic-unit-tests-glibc64
|
||||
|
||||
|
||||
Gathering test coverage
|
||||
-----------------------
|
||||
|
||||
For either host or target coverage, you must first:
|
||||
|
||||
* `$ export NATIVE_COVERAGE=true`
|
||||
* Note that the build system is ignorant to this flag being toggled, i.e. if
|
||||
you change this flag, you will have to manually rebuild bionic.
|
||||
* Set `bionic_coverage=true` in `libc/Android.mk` and `libm/Android.mk`.
|
||||
|
||||
### Coverage from device tests
|
||||
|
||||
$ mma
|
||||
$ adb sync
|
||||
$ adb shell \
|
||||
GCOV_PREFIX=/data/local/tmp/gcov \
|
||||
GCOV_PREFIX_STRIP=`echo $ANDROID_BUILD_TOP | grep -o / | wc -l` \
|
||||
/data/nativetest/bionic-unit-tests/bionic-unit-tests32
|
||||
$ acov
|
||||
|
||||
`acov` will pull all coverage information from the device, push it to the right
|
||||
directories, run `lcov`, and open the coverage report in your browser.
|
||||
|
||||
### Coverage from host tests
|
||||
|
||||
First, build and run the host tests as usual (see above).
|
||||
|
||||
$ croot
|
||||
$ lcov -c -d $ANDROID_PRODUCT_OUT -o coverage.info
|
||||
$ genhtml -o covreport coverage.info # or lcov --list coverage.info
|
||||
|
||||
The coverage report is now available at `covreport/index.html`.
|
@@ -49,9 +49,8 @@ LOCAL_MODULE_STEM_64 := bionic-benchmarks64
|
||||
LOCAL_MULTILIB := both
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CFLAGS += $(benchmark_c_flags)
|
||||
LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
|
||||
LOCAL_SHARED_LIBRARIES += libstlport
|
||||
LOCAL_SRC_FILES := $(benchmark_src_files)
|
||||
LOCAL_CXX_STL := libc++
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
|
||||
|
@@ -20,8 +20,8 @@
|
||||
#include <math.h>
|
||||
|
||||
// Avoid optimization.
|
||||
double d;
|
||||
double v;
|
||||
volatile double d;
|
||||
volatile double v;
|
||||
|
||||
static void BM_math_sqrt(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
@@ -105,3 +105,35 @@ static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
|
||||
|
||||
static void BM_pthread_rw_lock_read(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_t lock;
|
||||
pthread_rwlock_init(&lock, NULL);
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
pthread_rwlock_rdlock(&lock);
|
||||
pthread_rwlock_unlock(&lock);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_destroy(&lock);
|
||||
}
|
||||
BENCHMARK(BM_pthread_rw_lock_read);
|
||||
|
||||
static void BM_pthread_rw_lock_write(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_t lock;
|
||||
pthread_rwlock_init(&lock, NULL);
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
pthread_rwlock_wrlock(&lock);
|
||||
pthread_rwlock_unlock(&lock);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_destroy(&lock);
|
||||
}
|
||||
BENCHMARK(BM_pthread_rw_lock_write);
|
||||
|
112
libc/Android.mk
112
libc/Android.mk
@@ -1,5 +1,7 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
bionic_coverage := false
|
||||
|
||||
# Make everything depend on any changes to included makefiles.
|
||||
libc_common_additional_dependencies := $(LOCAL_PATH)/Android.mk
|
||||
|
||||
@@ -38,8 +40,6 @@ endif
|
||||
# =========================================================
|
||||
libc_common_src_files := \
|
||||
bionic/bindresvport.c \
|
||||
bionic/daemon.c \
|
||||
bionic/err.c \
|
||||
bionic/ether_aton.c \
|
||||
bionic/ether_ntoa.c \
|
||||
bionic/fts.c \
|
||||
@@ -51,19 +51,16 @@ libc_common_src_files := \
|
||||
bionic/ioctl.c \
|
||||
bionic/isatty.c \
|
||||
bionic/memmem.c \
|
||||
bionic/pathconf.c \
|
||||
bionic/pututline.c \
|
||||
bionic/sched_cpualloc.c \
|
||||
bionic/sched_cpucount.c \
|
||||
bionic/semaphore.c \
|
||||
bionic/sigblock.c \
|
||||
bionic/siginterrupt.c \
|
||||
bionic/sigsetmask.c \
|
||||
bionic/system_properties_compat.c \
|
||||
stdio/findfp.c \
|
||||
stdio/fread.c \
|
||||
stdio/snprintf.c\
|
||||
stdio/sprintf.c \
|
||||
stdio/stdio_ext.cpp \
|
||||
|
||||
# Fortify implementations of libc functions.
|
||||
libc_common_src_files += \
|
||||
@@ -92,6 +89,7 @@ libc_bionic_src_files := \
|
||||
bionic/access.cpp \
|
||||
bionic/assert.cpp \
|
||||
bionic/atof.cpp \
|
||||
bionic/bionic_systrace.cpp \
|
||||
bionic/bionic_time_conversions.cpp \
|
||||
bionic/brk.cpp \
|
||||
bionic/c16rtomb.cpp \
|
||||
@@ -100,6 +98,7 @@ libc_bionic_src_files := \
|
||||
bionic/chown.cpp \
|
||||
bionic/clearenv.cpp \
|
||||
bionic/clock.cpp \
|
||||
bionic/clock_nanosleep.cpp \
|
||||
bionic/clone.cpp \
|
||||
bionic/__cmsg_nxthdr.cpp \
|
||||
bionic/connect.cpp \
|
||||
@@ -123,6 +122,7 @@ libc_bionic_src_files := \
|
||||
bionic/getpgrp.cpp \
|
||||
bionic/getpid.cpp \
|
||||
bionic/gettid.cpp \
|
||||
bionic/__gnu_basename.cpp \
|
||||
bionic/inotify_init.cpp \
|
||||
bionic/lchown.cpp \
|
||||
bionic/lfs64_support.cpp \
|
||||
@@ -134,6 +134,7 @@ libc_bionic_src_files := \
|
||||
bionic/link.cpp \
|
||||
bionic/locale.cpp \
|
||||
bionic/lstat.cpp \
|
||||
bionic/malloc_info.cpp \
|
||||
bionic/mbrtoc16.cpp \
|
||||
bionic/mbrtoc32.cpp \
|
||||
bionic/mbstate.cpp \
|
||||
@@ -143,6 +144,7 @@ libc_bionic_src_files := \
|
||||
bionic/mntent.cpp \
|
||||
bionic/NetdClientDispatch.cpp \
|
||||
bionic/open.cpp \
|
||||
bionic/pathconf.cpp \
|
||||
bionic/pause.cpp \
|
||||
bionic/pipe.cpp \
|
||||
bionic/poll.cpp \
|
||||
@@ -182,6 +184,7 @@ libc_bionic_src_files := \
|
||||
bionic/scandir.cpp \
|
||||
bionic/sched_getaffinity.cpp \
|
||||
bionic/sched_getcpu.cpp \
|
||||
bionic/semaphore.cpp \
|
||||
bionic/send.cpp \
|
||||
bionic/setegid.cpp \
|
||||
bionic/__set_errno.cpp \
|
||||
@@ -240,9 +243,6 @@ libc_upstream_freebsd_src_files := \
|
||||
upstream-freebsd/lib/libc/gen/ldexp.c \
|
||||
upstream-freebsd/lib/libc/gen/sleep.c \
|
||||
upstream-freebsd/lib/libc/gen/usleep.c \
|
||||
upstream-freebsd/lib/libc/stdio/fclose.c \
|
||||
upstream-freebsd/lib/libc/stdio/flags.c \
|
||||
upstream-freebsd/lib/libc/stdio/fopen.c \
|
||||
upstream-freebsd/lib/libc/stdlib/abs.c \
|
||||
upstream-freebsd/lib/libc/stdlib/getopt_long.c \
|
||||
upstream-freebsd/lib/libc/stdlib/imaxabs.c \
|
||||
@@ -288,7 +288,6 @@ libc_upstream_netbsd_src_files := \
|
||||
upstream-netbsd/lib/libc/stdlib/div.c \
|
||||
upstream-netbsd/lib/libc/stdlib/drand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/erand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/insque.c \
|
||||
upstream-netbsd/lib/libc/stdlib/jrand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/ldiv.c \
|
||||
upstream-netbsd/lib/libc/stdlib/lldiv.c \
|
||||
@@ -297,14 +296,12 @@ libc_upstream_netbsd_src_files := \
|
||||
upstream-netbsd/lib/libc/stdlib/nrand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/_rand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/rand_r.c \
|
||||
upstream-netbsd/lib/libc/stdlib/remque.c \
|
||||
upstream-netbsd/lib/libc/stdlib/seed48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/srand48.c \
|
||||
upstream-netbsd/lib/libc/string/memccpy.c \
|
||||
upstream-netbsd/lib/libc/string/strcasestr.c \
|
||||
upstream-netbsd/lib/libc/string/strcoll.c \
|
||||
upstream-netbsd/lib/libc/string/strxfrm.c \
|
||||
upstream-netbsd/lib/libc/unistd/killpg.c \
|
||||
|
||||
libc_upstream_openbsd_gdtoa_src_files := \
|
||||
upstream-openbsd/android/gdtoa_support.cpp \
|
||||
@@ -334,10 +331,14 @@ libc_upstream_openbsd_gdtoa_src_files_64 := \
|
||||
upstream-openbsd/lib/libc/gdtoa/strtorQ.c \
|
||||
|
||||
libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/compat-43/killpg.c \
|
||||
upstream-openbsd/lib/libc/crypt/arc4random.c \
|
||||
upstream-openbsd/lib/libc/crypt/arc4random_uniform.c \
|
||||
upstream-openbsd/lib/libc/gen/alarm.c \
|
||||
upstream-openbsd/lib/libc/gen/ctype_.c \
|
||||
upstream-openbsd/lib/libc/gen/daemon.c \
|
||||
upstream-openbsd/lib/libc/gen/err.c \
|
||||
upstream-openbsd/lib/libc/gen/errx.c \
|
||||
upstream-openbsd/lib/libc/gen/exec.c \
|
||||
upstream-openbsd/lib/libc/gen/fnmatch.c \
|
||||
upstream-openbsd/lib/libc/gen/ftok.c \
|
||||
@@ -347,6 +348,12 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/gen/time.c \
|
||||
upstream-openbsd/lib/libc/gen/tolower_.c \
|
||||
upstream-openbsd/lib/libc/gen/toupper_.c \
|
||||
upstream-openbsd/lib/libc/gen/verr.c \
|
||||
upstream-openbsd/lib/libc/gen/verrx.c \
|
||||
upstream-openbsd/lib/libc/gen/vwarn.c \
|
||||
upstream-openbsd/lib/libc/gen/vwarnx.c \
|
||||
upstream-openbsd/lib/libc/gen/warn.c \
|
||||
upstream-openbsd/lib/libc/gen/warnx.c \
|
||||
upstream-openbsd/lib/libc/locale/btowc.c \
|
||||
upstream-openbsd/lib/libc/locale/mbrlen.c \
|
||||
upstream-openbsd/lib/libc/locale/mbstowcs.c \
|
||||
@@ -380,6 +387,7 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdio/asprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/clrerr.c \
|
||||
upstream-openbsd/lib/libc/stdio/dprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fclose.c \
|
||||
upstream-openbsd/lib/libc/stdio/fdopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/feof.c \
|
||||
upstream-openbsd/lib/libc/stdio/ferror.c \
|
||||
@@ -391,12 +399,17 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdio/fgetwc.c \
|
||||
upstream-openbsd/lib/libc/stdio/fgetws.c \
|
||||
upstream-openbsd/lib/libc/stdio/fileno.c \
|
||||
upstream-openbsd/lib/libc/stdio/findfp.c \
|
||||
upstream-openbsd/lib/libc/stdio/flags.c \
|
||||
upstream-openbsd/lib/libc/stdio/fmemopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/fopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/fprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fpurge.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputc.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputs.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputwc.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputws.c \
|
||||
upstream-openbsd/lib/libc/stdio/fread.c \
|
||||
upstream-openbsd/lib/libc/stdio/freopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/fscanf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fseek.c \
|
||||
@@ -418,6 +431,8 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdio/getwchar.c \
|
||||
upstream-openbsd/lib/libc/stdio/makebuf.c \
|
||||
upstream-openbsd/lib/libc/stdio/mktemp.c \
|
||||
upstream-openbsd/lib/libc/stdio/open_memstream.c \
|
||||
upstream-openbsd/lib/libc/stdio/open_wmemstream.c \
|
||||
upstream-openbsd/lib/libc/stdio/perror.c \
|
||||
upstream-openbsd/lib/libc/stdio/printf.c \
|
||||
upstream-openbsd/lib/libc/stdio/putc.c \
|
||||
@@ -466,7 +481,9 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdlib/atoll.c \
|
||||
upstream-openbsd/lib/libc/stdlib/exit.c \
|
||||
upstream-openbsd/lib/libc/stdlib/getenv.c \
|
||||
upstream-openbsd/lib/libc/stdlib/insque.c \
|
||||
upstream-openbsd/lib/libc/stdlib/lsearch.c \
|
||||
upstream-openbsd/lib/libc/stdlib/remque.c \
|
||||
upstream-openbsd/lib/libc/stdlib/setenv.c \
|
||||
upstream-openbsd/lib/libc/stdlib/strtoimax.c \
|
||||
upstream-openbsd/lib/libc/stdlib/strtol.c \
|
||||
@@ -586,7 +603,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_stack_protector
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -624,7 +643,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes) $(LOCAL_PATH)/tzcode/
|
||||
LOCAL_MODULE := libc_tzcode
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -642,7 +663,13 @@ LOCAL_SRC_FILES := \
|
||||
upstream-netbsd/lib/libc/isc/ev_timers.c \
|
||||
upstream-netbsd/lib/libc/resolv/mtctxres.c \
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
# We use the OpenBSD res_random.
|
||||
LOCAL_CFLAGS += \
|
||||
-Dres_randomid=__res_randomid
|
||||
LOCAL_SRC_FILES += \
|
||||
upstream-openbsd/lib/libc/net/res_random.c \
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
$(libc_common_cflags) \
|
||||
-DANDROID_CHANGES \
|
||||
-DINET6 \
|
||||
@@ -660,7 +687,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_dns
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -689,7 +718,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_freebsd
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_freebsd_src_files))
|
||||
@@ -720,7 +751,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_netbsd
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_netbsd_src_files))
|
||||
@@ -746,7 +779,10 @@ endif
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-Wno-sign-compare -Wno-uninitialized -Wno-unused-parameter \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-sign-compare \
|
||||
-Wno-uninitialized \
|
||||
-Wno-unused-parameter \
|
||||
-I$(LOCAL_PATH)/private \
|
||||
-I$(LOCAL_PATH)/upstream-openbsd/android/include \
|
||||
-I$(LOCAL_PATH)/upstream-openbsd/lib/libc/include \
|
||||
@@ -758,7 +794,9 @@ LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_openbsd
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_openbsd_src_files))
|
||||
@@ -797,7 +835,9 @@ LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_gdtoa
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -820,11 +860,13 @@ endif
|
||||
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_MODULE := libc_bionic
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
|
||||
@@ -843,12 +885,13 @@ LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_MODULE := libc_cxa
|
||||
# GCC refuses to hide new/delete
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_CLANG := true # GCC refuses to hide new/delete
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -866,7 +909,9 @@ endif
|
||||
LOCAL_MODULE := libc_syscalls
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -885,7 +930,9 @@ LOCAL_MODULE := libc_aeabi
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) -fno-builtin
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -922,10 +969,12 @@ ifneq ($(MALLOC_IMPL),dlmalloc)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
|
||||
endif
|
||||
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
|
||||
# TODO: split out the asflags.
|
||||
LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_common_src_files))
|
||||
@@ -961,7 +1010,9 @@ LOCAL_MODULE := libc_nomalloc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_static_src_files))
|
||||
@@ -982,6 +1033,8 @@ LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_malloc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -1007,7 +1060,9 @@ LOCAL_MODULE := libc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_static_src_files))
|
||||
@@ -1049,6 +1104,7 @@ LOCAL_STRIP_MODULE := keep_symbols
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libdl
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
|
||||
# We'd really like to do this for all architectures, but since this wasn't done
|
||||
@@ -1068,6 +1124,7 @@ LOCAL_SRC_FILES_arm += \
|
||||
arch-common/bionic/crtbegin_so.c \
|
||||
arch-arm/bionic/atexit_legacy.c \
|
||||
arch-common/bionic/crtend_so.S
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -1085,10 +1142,7 @@ ifneq ($(TARGET_BUILD_VARIANT),user)
|
||||
# ========================================================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-DMALLOC_LEAK_CHECK \
|
||||
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
|
||||
@@ -1108,14 +1162,16 @@ LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libc libdl
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
# Only need this for arm since libc++ uses its own unwind code that
|
||||
# doesn't mix with the other default unwind code.
|
||||
LOCAL_STATIC_LIBRARIES_arm := libc++
|
||||
LOCAL_STATIC_LIBRARIES_arm := libunwind_llvm
|
||||
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
|
||||
|
||||
# Don't install on release build
|
||||
LOCAL_MODULE_TAGS := eng debug
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1144,10 +1200,12 @@ LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libc libdl
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
|
||||
# Don't install on release build
|
||||
LOCAL_MODULE_TAGS := eng debug
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1164,26 +1222,30 @@ libstdcxx_common_src_files := \
|
||||
bionic/libc_logging.cpp \
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
|
||||
LOCAL_MODULE:= libstdc++
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# ========================================================
|
||||
# libstdc++.a
|
||||
# ========================================================
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
|
||||
LOCAL_MODULE:= libstdc++
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
|
130
libc/NOTICE
130
libc/NOTICE
@@ -2510,35 +2510,6 @@ SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1993
|
||||
The Regents of the University of California. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1993
|
||||
The Regents of the University of California. All rights reserved.
|
||||
|
||||
@@ -3131,38 +3102,6 @@ SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1999 Kungliga Tekniska Högskolan
|
||||
(Royal Institute of Technology, Stockholm, Sweden).
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of KTH nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2000 Ben Harris.
|
||||
Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
All rights reserved.
|
||||
@@ -4422,6 +4361,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
|
||||
Copyright (c) 2009 Ted Unangst
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2011 The Android Open Source Project
|
||||
Copyright (c) 2008 ARM Ltd
|
||||
All rights reserved.
|
||||
@@ -4853,6 +4825,42 @@ SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
|
||||
Copyright 2008 Damien Miller <djm@openbsd.org>
|
||||
All rights reserved.
|
||||
|
||||
Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
|
||||
such a mathematical system to generate more random (yet non-repeating)
|
||||
ids to solve the resolver/named problem. But Niels designed the
|
||||
actual system based on the constraints.
|
||||
|
||||
Later modified by Damien Miller to wrap the LCG output in a 15-bit
|
||||
permutation generator based on a Luby-Rackoff block cipher. This
|
||||
ensures the output is non-repeating and preserves the MSB twiddle
|
||||
trick, but makes it more resistant to LCG prediction.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright 2000 David E. O'Brien, John D. Polstra.
|
||||
All rights reserved.
|
||||
|
||||
|
@@ -202,9 +202,9 @@ int swapoff(const char*) all
|
||||
int settimeofday(const struct timeval*, const struct timezone*) all
|
||||
clock_t times(struct tms*) all
|
||||
int nanosleep(const struct timespec*, struct timespec*) all
|
||||
int clock_settime(clockid_t clk_id, const struct timespec* tp) all
|
||||
int clock_getres(clockid_t clk_id, struct timespec* res) all
|
||||
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec* req, struct timespec* rem) all
|
||||
int clock_settime(clockid_t, const struct timespec*) all
|
||||
int clock_getres(clockid_t, struct timespec*) all
|
||||
int __clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) all
|
||||
int getitimer(int, const struct itimerval*) all
|
||||
int setitimer(int, const struct itimerval*, struct itimerval*) all
|
||||
int __timer_create:timer_create(clockid_t clockid, struct sigevent* evp, __kernel_timer_t* timerid) all
|
||||
@@ -321,7 +321,7 @@ int __set_tls:__ARM_NR_set_tls(void*) arm
|
||||
int cacheflush:__ARM_NR_cacheflush(long start, long end, long flags) arm
|
||||
|
||||
# MIPS-specific
|
||||
int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips,mips64
|
||||
int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips
|
||||
int __set_tls:set_thread_area(void*) mips,mips64
|
||||
|
||||
# x86-specific
|
||||
|
@@ -39,6 +39,9 @@
|
||||
|
||||
extern int __cxa_atexit(void (*)(void*), void*, void*);
|
||||
|
||||
// All of these are weak symbols to avoid multiple definition errors when
|
||||
// linking with libstdc++-v3 or compiler-rt.
|
||||
|
||||
/* The "C++ ABI for ARM" document states that static C++ constructors,
|
||||
* which are called from the .init_array, should manually call
|
||||
* __aeabi_atexit() to register static destructors explicitly.
|
||||
@@ -47,35 +50,35 @@ extern int __cxa_atexit(void (*)(void*), void*, void*);
|
||||
* variable from the shared object that contains the constructor/destructor
|
||||
*/
|
||||
|
||||
// Make this a weak symbol to avoid a multiple definition error when linking with libstdc++-v3.
|
||||
int __attribute__((weak))
|
||||
__aeabi_atexit(void *object, void (*destructor) (void *), void *dso_handle) {
|
||||
return __cxa_atexit(destructor, object, dso_handle);
|
||||
}
|
||||
|
||||
|
||||
void __aeabi_memcpy8(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak))
|
||||
__aeabi_memcpy8(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __aeabi_memcpy4(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memcpy4(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __aeabi_memcpy(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memcpy(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
|
||||
void __aeabi_memmove8(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memmove8(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __aeabi_memmove4(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memmove4(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __aeabi_memmove(void *dest, const void *src, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memmove(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
@@ -84,27 +87,27 @@ void __aeabi_memmove(void *dest, const void *src, size_t n) {
|
||||
* This allows __aeabi_memclr to tail-call __aeabi_memset
|
||||
*/
|
||||
|
||||
void __aeabi_memset8(void *dest, size_t n, int c) {
|
||||
void __attribute__((weak)) __aeabi_memset8(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __aeabi_memset4(void *dest, size_t n, int c) {
|
||||
void __attribute__((weak)) __aeabi_memset4(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __aeabi_memset(void *dest, size_t n, int c) {
|
||||
void __attribute__((weak)) __aeabi_memset(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
|
||||
void __aeabi_memclr8(void *dest, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memclr8(void *dest, size_t n) {
|
||||
__aeabi_memset8(dest, n, 0);
|
||||
}
|
||||
|
||||
void __aeabi_memclr4(void *dest, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memclr4(void *dest, size_t n) {
|
||||
__aeabi_memset4(dest, n, 0);
|
||||
}
|
||||
|
||||
void __aeabi_memclr(void *dest, size_t n) {
|
||||
void __attribute__((weak)) __aeabi_memclr(void *dest, size_t n) {
|
||||
__aeabi_memset(dest, n, 0);
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ ENTRY(_longjmp)
|
||||
|
||||
/* validation failed, die die die. */
|
||||
botch:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
bl longjmperror
|
||||
bl abort
|
||||
b . - 8 /* Cannot get here */
|
||||
END(_longjmp)
|
||||
|
@@ -40,5 +40,5 @@ ENTRY(abort)
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r3, 0
|
||||
.cfi_rel_offset r14, 4
|
||||
bl PIC_SYM(__libc_android_abort, PLT)
|
||||
bl __libc_android_abort
|
||||
END(abort)
|
||||
|
@@ -56,7 +56,7 @@ ENTRY(setjmp)
|
||||
.cfi_rel_offset r14, 4
|
||||
mov r0, #0x00000000
|
||||
|
||||
bl PIC_SYM(sigblock, PLT)
|
||||
bl sigblock
|
||||
mov r1, r0
|
||||
|
||||
ldmfd sp!, {r0, r14}
|
||||
@@ -108,7 +108,7 @@ ENTRY(longjmp)
|
||||
.cfi_adjust_cfa_offset 4
|
||||
|
||||
mov r0, r2
|
||||
bl PIC_SYM(sigsetmask, PLT)
|
||||
bl sigsetmask
|
||||
|
||||
add sp, sp, #4 /* unalign the stack */
|
||||
.cfi_adjust_cfa_offset -4
|
||||
@@ -147,7 +147,7 @@ ENTRY(longjmp)
|
||||
|
||||
/* validation failed, die die die. */
|
||||
botch:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
bl longjmperror
|
||||
bl abort
|
||||
b . - 8 /* Cannot get here */
|
||||
END(longjmp)
|
||||
|
@@ -33,8 +33,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define _ALIGN_TEXT .align 0
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
@@ -50,8 +48,8 @@
|
||||
|
||||
ENTRY(sigsetjmp)
|
||||
teq r1, #0
|
||||
beq PIC_SYM(_setjmp, PLT)
|
||||
b PIC_SYM(setjmp, PLT)
|
||||
beq _setjmp
|
||||
b setjmp
|
||||
END(sigsetjmp)
|
||||
|
||||
.L_setjmp_magic:
|
||||
@@ -61,6 +59,6 @@ ENTRY(siglongjmp)
|
||||
ldr r2, .L_setjmp_magic
|
||||
ldr r3, [r0]
|
||||
teq r2, r3
|
||||
beq PIC_SYM(_longjmp, PLT)
|
||||
b PIC_SYM(longjmp, PLT)
|
||||
beq _longjmp
|
||||
b longjmp
|
||||
END(siglongjmp)
|
||||
|
@@ -39,7 +39,7 @@
|
||||
|
||||
ENTRY(__memcpy_chk)
|
||||
cmp r2, r3
|
||||
bhi __memcpy_chk_fail
|
||||
bgt fortify_check_failed
|
||||
|
||||
// Fall through to memcpy...
|
||||
END(__memcpy_chk)
|
||||
@@ -49,14 +49,11 @@ ENTRY(memcpy)
|
||||
* ARM ABI. Since we have to save R0, we might as well save R4
|
||||
* which we can use for better pipelining of the reads below
|
||||
*/
|
||||
.save {r0, r4, lr}
|
||||
stmfd sp!, {r0, r4, lr}
|
||||
.cfi_def_cfa_offset 12
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r4, 4
|
||||
.cfi_rel_offset lr, 8
|
||||
/* Making room for r5-r11 which will be spilled later */
|
||||
.pad #28
|
||||
sub sp, sp, #28
|
||||
.cfi_adjust_cfa_offset 28
|
||||
|
||||
// preload the destination because we'll align it to a cache line
|
||||
// with small writes. Also start the source "pump".
|
||||
@@ -66,14 +63,14 @@ ENTRY(memcpy)
|
||||
|
||||
/* it simplifies things to take care of len<4 early */
|
||||
cmp r2, #4
|
||||
blo .Lcopy_last_3_and_return
|
||||
blo copy_last_3_and_return
|
||||
|
||||
/* compute the offset to align the source
|
||||
* offset = (4-(src&3))&3 = -src & 3
|
||||
*/
|
||||
rsb r3, r1, #0
|
||||
ands r3, r3, #3
|
||||
beq .Lsrc_aligned
|
||||
beq src_aligned
|
||||
|
||||
/* align source to 32 bits. We need to insert 2 instructions between
|
||||
* a ldr[b|h] and str[b|h] because byte and half-word instructions
|
||||
@@ -88,12 +85,12 @@ ENTRY(memcpy)
|
||||
strcsb r4, [r0], #1
|
||||
strcsb r12,[r0], #1
|
||||
|
||||
.Lsrc_aligned:
|
||||
src_aligned:
|
||||
|
||||
/* see if src and dst are aligned together (congruent) */
|
||||
eor r12, r0, r1
|
||||
tst r12, #3
|
||||
bne .Lnon_congruent
|
||||
bne non_congruent
|
||||
|
||||
/* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
||||
* frame. Don't update sp.
|
||||
@@ -103,7 +100,7 @@ ENTRY(memcpy)
|
||||
/* align the destination to a cache-line */
|
||||
rsb r3, r0, #0
|
||||
ands r3, r3, #0x1C
|
||||
beq .Lcongruent_aligned32
|
||||
beq congruent_aligned32
|
||||
cmp r3, r2
|
||||
andhi r3, r2, #0x1C
|
||||
|
||||
@@ -118,14 +115,14 @@ ENTRY(memcpy)
|
||||
strne r10,[r0], #4
|
||||
sub r2, r2, r3
|
||||
|
||||
.Lcongruent_aligned32:
|
||||
congruent_aligned32:
|
||||
/*
|
||||
* here source is aligned to 32 bytes.
|
||||
*/
|
||||
|
||||
.Lcached_aligned32:
|
||||
cached_aligned32:
|
||||
subs r2, r2, #32
|
||||
blo .Lless_than_32_left
|
||||
blo less_than_32_left
|
||||
|
||||
/*
|
||||
* We preload a cache-line up to 64 bytes ahead. On the 926, this will
|
||||
@@ -163,7 +160,10 @@ ENTRY(memcpy)
|
||||
|
||||
add r2, r2, #32
|
||||
|
||||
.Lless_than_32_left:
|
||||
|
||||
|
||||
|
||||
less_than_32_left:
|
||||
/*
|
||||
* less than 32 bytes left at this point (length in r2)
|
||||
*/
|
||||
@@ -197,7 +197,7 @@ ENTRY(memcpy)
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
.Lnon_congruent:
|
||||
non_congruent:
|
||||
/*
|
||||
* here source is aligned to 4 bytes
|
||||
* but destination is not.
|
||||
@@ -207,9 +207,9 @@ ENTRY(memcpy)
|
||||
* partial words in the shift queue)
|
||||
*/
|
||||
cmp r2, #4
|
||||
blo .Lcopy_last_3_and_return
|
||||
blo copy_last_3_and_return
|
||||
|
||||
/* Use post-increment mode for stm to spill r5-r11 to reserved stack
|
||||
/* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
||||
* frame. Don't update sp.
|
||||
*/
|
||||
stmea sp, {r5-r11}
|
||||
@@ -236,7 +236,7 @@ ENTRY(memcpy)
|
||||
movcs r3, r3, lsr #8
|
||||
|
||||
cmp r2, #4
|
||||
blo .Lpartial_word_tail
|
||||
blo partial_word_tail
|
||||
|
||||
/* Align destination to 32 bytes (cache line boundary) */
|
||||
1: tst r0, #0x1c
|
||||
@@ -248,11 +248,11 @@ ENTRY(memcpy)
|
||||
str r4, [r0], #4
|
||||
cmp r2, #4
|
||||
bhs 1b
|
||||
blo .Lpartial_word_tail
|
||||
blo partial_word_tail
|
||||
|
||||
/* copy 32 bytes at a time */
|
||||
2: subs r2, r2, #32
|
||||
blo .Lless_than_thirtytwo
|
||||
blo less_than_thirtytwo
|
||||
|
||||
/* Use immediate mode for the shifts, because there is an extra cycle
|
||||
* for register shifts, which could account for up to 50% of
|
||||
@@ -260,11 +260,11 @@ ENTRY(memcpy)
|
||||
*/
|
||||
|
||||
cmp r12, #24
|
||||
beq .Lloop24
|
||||
beq loop24
|
||||
cmp r12, #8
|
||||
beq .Lloop8
|
||||
beq loop8
|
||||
|
||||
.Lloop16:
|
||||
loop16:
|
||||
ldr r12, [r1], #4
|
||||
1: mov r4, r12
|
||||
ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
||||
@@ -289,9 +289,9 @@ ENTRY(memcpy)
|
||||
stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
||||
mov r3, r11, lsr #16
|
||||
bhs 1b
|
||||
b .Lless_than_thirtytwo
|
||||
b less_than_thirtytwo
|
||||
|
||||
.Lloop8:
|
||||
loop8:
|
||||
ldr r12, [r1], #4
|
||||
1: mov r4, r12
|
||||
ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
||||
@@ -316,9 +316,9 @@ ENTRY(memcpy)
|
||||
stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
||||
mov r3, r11, lsr #8
|
||||
bhs 1b
|
||||
b .Lless_than_thirtytwo
|
||||
b less_than_thirtytwo
|
||||
|
||||
.Lloop24:
|
||||
loop24:
|
||||
ldr r12, [r1], #4
|
||||
1: mov r4, r12
|
||||
ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
||||
@@ -345,12 +345,12 @@ ENTRY(memcpy)
|
||||
bhs 1b
|
||||
|
||||
|
||||
.Lless_than_thirtytwo:
|
||||
less_than_thirtytwo:
|
||||
/* copy the last 0 to 31 bytes of the source */
|
||||
rsb r12, lr, #32 /* we corrupted r12, recompute it */
|
||||
add r2, r2, #32
|
||||
cmp r2, #4
|
||||
blo .Lpartial_word_tail
|
||||
blo partial_word_tail
|
||||
|
||||
1: ldr r5, [r1], #4
|
||||
sub r2, r2, #4
|
||||
@@ -360,7 +360,7 @@ ENTRY(memcpy)
|
||||
cmp r2, #4
|
||||
bhs 1b
|
||||
|
||||
.Lpartial_word_tail:
|
||||
partial_word_tail:
|
||||
/* we have a partial word in the input buffer */
|
||||
movs r5, lr, lsl #(31-3)
|
||||
strmib r3, [r0], #1
|
||||
@@ -372,7 +372,7 @@ ENTRY(memcpy)
|
||||
/* Refill spilled registers from the stack. Don't update sp. */
|
||||
ldmfd sp, {r5-r11}
|
||||
|
||||
.Lcopy_last_3_and_return:
|
||||
copy_last_3_and_return:
|
||||
movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
|
||||
ldrmib r2, [r1], #1
|
||||
ldrcsb r3, [r1], #1
|
||||
@@ -385,15 +385,9 @@ ENTRY(memcpy)
|
||||
add sp, sp, #28
|
||||
ldmfd sp!, {r0, r4, lr}
|
||||
bx lr
|
||||
END(memcpy)
|
||||
|
||||
// Only reached when the __memcpy_chk check fails.
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
fortify_check_failed:
|
||||
ldr r0, error_message
|
||||
ldr r1, error_code
|
||||
1:
|
||||
@@ -403,7 +397,7 @@ error_code:
|
||||
.word BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
|
||||
error_message:
|
||||
.word error_string-(1b+8)
|
||||
END(__memcpy_chk_fail)
|
||||
END(memcpy)
|
||||
|
||||
.data
|
||||
error_string:
|
||||
|
@@ -38,9 +38,7 @@
|
||||
#ifndef _ARM32_ASM_H_
|
||||
#define _ARM32_ASM_H_
|
||||
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 0
|
||||
#endif
|
||||
#define __bionic_asm_align 0
|
||||
|
||||
#undef __bionic_asm_custom_entry
|
||||
#undef __bionic_asm_custom_end
|
||||
@@ -50,10 +48,4 @@
|
||||
#undef __bionic_asm_function_type
|
||||
#define __bionic_asm_function_type #function
|
||||
|
||||
#if defined(__ELF__) && defined(PIC)
|
||||
#define PIC_SYM(x,y) x ## ( ## y ## )
|
||||
#else
|
||||
#define PIC_SYM(x,y) x
|
||||
#endif
|
||||
|
||||
#endif /* !_ARM_ASM_H_ */
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(clock_nanosleep)
|
||||
ENTRY(__clock_nanosleep)
|
||||
mov ip, r7
|
||||
ldr r7, =__NR_clock_nanosleep
|
||||
swi #0
|
||||
@@ -11,4 +11,4 @@ ENTRY(clock_nanosleep)
|
||||
bxls lr
|
||||
neg r0, r0
|
||||
b __set_errno_internal
|
||||
END(clock_nanosleep)
|
||||
END(__clock_nanosleep)
|
@@ -105,7 +105,7 @@ ENTRY(_longjmp)
|
||||
|
||||
/* validation failed, die die die */
|
||||
.L_fail:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
bl longjmperror
|
||||
bl abort
|
||||
b . - 8 /* Cannot get here */
|
||||
END(_longjmp)
|
||||
|
@@ -45,7 +45,7 @@ ENTRY(setjmp)
|
||||
stp x0, x30, [sp, #-16]!
|
||||
|
||||
mov x0, xzr
|
||||
bl PIC_SYM(sigblock, PLT)
|
||||
bl sigblock
|
||||
mov w1, w0
|
||||
|
||||
ldp x0, x30, [sp], #16
|
||||
@@ -117,7 +117,7 @@ ENTRY(longjmp)
|
||||
|
||||
/* validation failed, die die die */
|
||||
.L_fail:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
bl longjmperror
|
||||
bl abort
|
||||
b . - 8 /* Cannot get here */
|
||||
END(longjmp)
|
||||
|
@@ -35,8 +35,8 @@
|
||||
*/
|
||||
|
||||
ENTRY(sigsetjmp)
|
||||
cbz w1, PIC_SYM(_setjmp, PLT)
|
||||
b PIC_SYM(setjmp, PLT)
|
||||
cbz w1, _setjmp
|
||||
b setjmp
|
||||
END(sigsetjmp)
|
||||
|
||||
.L_setjmp_magic:
|
||||
@@ -46,6 +46,6 @@ ENTRY(siglongjmp)
|
||||
ldr w2, .L_setjmp_magic
|
||||
ldr w3, [x0]
|
||||
cmp w2, w3
|
||||
b.eq PIC_SYM(_longjmp, PLT)
|
||||
b PIC_SYM(longjmp, PLT)
|
||||
b.eq _longjmp
|
||||
b longjmp
|
||||
END(siglongjmp)
|
||||
|
@@ -38,17 +38,9 @@
|
||||
#ifndef _AARCH64_ASM_H_
|
||||
#define _AARCH64_ASM_H_
|
||||
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 0
|
||||
#endif
|
||||
#define __bionic_asm_align 0
|
||||
|
||||
#undef __bionic_asm_function_type
|
||||
#define __bionic_asm_function_type %function
|
||||
|
||||
#if defined(__ELF__) && defined(PIC)
|
||||
#define PIC_SYM(x,y) x ## ( ## y ## )
|
||||
#else
|
||||
#define PIC_SYM(x,y) x
|
||||
#endif
|
||||
|
||||
#endif /* _AARCH64_ASM_H_ */
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(clock_nanosleep)
|
||||
ENTRY(__clock_nanosleep)
|
||||
mov x8, __NR_clock_nanosleep
|
||||
svc #0
|
||||
|
||||
@@ -11,4 +11,5 @@ ENTRY(clock_nanosleep)
|
||||
b.hi __set_errno_internal
|
||||
|
||||
ret
|
||||
END(clock_nanosleep)
|
||||
END(__clock_nanosleep)
|
||||
.hidden __clock_nanosleep
|
@@ -28,9 +28,7 @@
|
||||
#ifndef _MIPS64_ASM_H
|
||||
#define _MIPS64_ASM_H
|
||||
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 4
|
||||
#endif
|
||||
#define __bionic_asm_align 4
|
||||
|
||||
#undef __bionic_asm_custom_entry
|
||||
#undef __bionic_asm_custom_end
|
||||
|
@@ -30,6 +30,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "mips-string-ops.h"
|
||||
|
||||
#define do_strlen_word(__av) {\
|
||||
@@ -47,8 +48,8 @@
|
||||
#define strlen my_strlen
|
||||
#endif
|
||||
|
||||
int
|
||||
strlen (const void *_a)
|
||||
size_t
|
||||
strlen (const char *_a)
|
||||
{
|
||||
int cnt = 0;
|
||||
unsigned x;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(clock_nanosleep)
|
||||
ENTRY(__clock_nanosleep)
|
||||
.set noreorder
|
||||
.cpload t9
|
||||
li v0, __NR_clock_nanosleep
|
||||
@@ -16,4 +16,4 @@ ENTRY(clock_nanosleep)
|
||||
j t9
|
||||
nop
|
||||
.set reorder
|
||||
END(clock_nanosleep)
|
||||
END(__clock_nanosleep)
|
@@ -52,7 +52,7 @@ LEAF(syscall,FRAMESZ)
|
||||
#else
|
||||
move a3, a4
|
||||
move a4, a5
|
||||
REG_L a5, FRAMESZ(sp)
|
||||
move a5, a6
|
||||
#endif
|
||||
syscall
|
||||
move a0, v0
|
||||
|
@@ -28,9 +28,7 @@
|
||||
#ifndef _MIPS64_ASM_H
|
||||
#define _MIPS64_ASM_H
|
||||
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 4
|
||||
#endif
|
||||
#define __bionic_asm_align 4
|
||||
|
||||
#undef __bionic_asm_custom_entry
|
||||
#undef __bionic_asm_custom_end
|
||||
|
@@ -49,7 +49,6 @@ libc_openbsd_src_files_mips64 += \
|
||||
libc_bionic_src_files_mips64 += \
|
||||
arch-mips64/bionic/__bionic_clone.S \
|
||||
arch-mips64/bionic/_exit_with_stack_teardown.S \
|
||||
arch-mips64/bionic/__get_sp.S \
|
||||
arch-mips64/bionic/_setjmp.S \
|
||||
arch-mips64/bionic/setjmp.S \
|
||||
arch-mips64/bionic/sigsetjmp.S \
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(clock_nanosleep)
|
||||
ENTRY(__clock_nanosleep)
|
||||
.set push
|
||||
.set noreorder
|
||||
li v0, __NR_clock_nanosleep
|
||||
@@ -22,4 +22,5 @@ ENTRY(clock_nanosleep)
|
||||
j t9
|
||||
move ra, t0
|
||||
.set pop
|
||||
END(clock_nanosleep)
|
||||
END(__clock_nanosleep)
|
||||
.hidden __clock_nanosleep
|
@@ -1,25 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(_flush_cache)
|
||||
.set push
|
||||
.set noreorder
|
||||
li v0, __NR_cacheflush
|
||||
syscall
|
||||
bnez a3, 1f
|
||||
move a0, v0
|
||||
j ra
|
||||
nop
|
||||
1:
|
||||
move t0, ra
|
||||
bal 2f
|
||||
nop
|
||||
2:
|
||||
.cpsetup ra, t1, 2b
|
||||
LA t9,__set_errno_internal
|
||||
.cpreturn
|
||||
j t9
|
||||
move ra, t0
|
||||
.set pop
|
||||
END(_flush_cache)
|
@@ -65,21 +65,21 @@ name: \
|
||||
ENTRY (wcslen)
|
||||
mov STR(%esp), %edx
|
||||
#endif
|
||||
cmp $0, (%edx)
|
||||
cmpl $0, (%edx)
|
||||
jz L(exit_tail0)
|
||||
cmp $0, 4(%edx)
|
||||
cmpl $0, 4(%edx)
|
||||
jz L(exit_tail1)
|
||||
cmp $0, 8(%edx)
|
||||
cmpl $0, 8(%edx)
|
||||
jz L(exit_tail2)
|
||||
cmp $0, 12(%edx)
|
||||
cmpl $0, 12(%edx)
|
||||
jz L(exit_tail3)
|
||||
cmp $0, 16(%edx)
|
||||
cmpl $0, 16(%edx)
|
||||
jz L(exit_tail4)
|
||||
cmp $0, 20(%edx)
|
||||
cmpl $0, 20(%edx)
|
||||
jz L(exit_tail5)
|
||||
cmp $0, 24(%edx)
|
||||
cmpl $0, 24(%edx)
|
||||
jz L(exit_tail6)
|
||||
cmp $0, 28(%edx)
|
||||
cmpl $0, 28(%edx)
|
||||
jz L(exit_tail7)
|
||||
|
||||
pxor %xmm0, %xmm0
|
||||
|
@@ -28,108 +28,10 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
// DWARF constants.
|
||||
#define DW_CFA_def_cfa_expression 0x0f
|
||||
#define DW_CFA_expression 0x10
|
||||
#define DW_EH_PE_pcrel 0x10
|
||||
#define DW_EH_PE_sdata4 0x0b
|
||||
#define DW_OP_breg4 0x74
|
||||
#define DW_OP_deref 0x06
|
||||
|
||||
// Offsets into struct sigcontext.
|
||||
#define OFFSET_EDI 16
|
||||
#define OFFSET_ESI 20
|
||||
#define OFFSET_EBP 24
|
||||
#define OFFSET_ESP 28
|
||||
#define OFFSET_EBX 32
|
||||
#define OFFSET_EDX 36
|
||||
#define OFFSET_ECX 40
|
||||
#define OFFSET_EAX 44
|
||||
#define OFFSET_EIP 56
|
||||
|
||||
// Non-standard DWARF constants for the x86 registers.
|
||||
#define DW_x86_REG_EAX 0
|
||||
#define DW_x86_REG_ECX 1
|
||||
#define DW_x86_REG_EDX 2
|
||||
#define DW_x86_REG_EBX 3
|
||||
#define DW_x86_REG_EBP 5
|
||||
#define DW_x86_REG_ESI 6
|
||||
#define DW_x86_REG_EDI 7
|
||||
#define DW_x86_REG_EIP 8
|
||||
|
||||
#define cfi_signal_frame_start(f) \
|
||||
.section .eh_frame,"a",@progbits; \
|
||||
.L ## f ## _START_EH_FRAME: \
|
||||
.long 2f - 1f; /* CIE length. */ \
|
||||
1:.long 0; /* CIE ID. */ \
|
||||
.byte 1; /* Version. */ \
|
||||
.string "zRS"; /* Augmentation string. */ \
|
||||
.uleb128 1; /* Code alignment factor. */ \
|
||||
.sleb128 -4; /* Data alignment factor. */ \
|
||||
.uleb128 DW_x86_REG_EIP; /* Return address register. */ \
|
||||
.uleb128 1; /* 1 byte of augmentation data. */ \
|
||||
.byte (DW_EH_PE_pcrel|DW_EH_PE_sdata4); /* FDE encoding. */ \
|
||||
.align 8; \
|
||||
2: \
|
||||
.long .L ## f ## _END_FDE - .L ## f ## _START_FDE; /* FDE length. */ \
|
||||
.L ## f ## _START_FDE: \
|
||||
.long .L ## f ## _START_FDE - .L ## f ## _START_EH_FRAME; /* CIE location. */ \
|
||||
.long (.L ## f ## _START - 1) - .; /* pcrel start address (see FDE encoding above). */ \
|
||||
.long .L ## f ## _END - (.L ## f ## _START - 1); /* Function this FDE applies to. */ \
|
||||
.uleb128 0; /* FDE augmentation length. */ \
|
||||
|
||||
#define cfi_signal_frame_end(f) \
|
||||
.L ## f ## _END_FDE: \
|
||||
|
||||
#define cfi_def_cfa(offset) \
|
||||
.byte DW_CFA_def_cfa_expression; \
|
||||
.uleb128 2f-1f; \
|
||||
1:.byte DW_OP_breg4; \
|
||||
.sleb128 offset; \
|
||||
.byte DW_OP_deref; \
|
||||
2: \
|
||||
|
||||
#define cfi_offset(reg_number,offset) \
|
||||
.byte DW_CFA_expression; \
|
||||
.uleb128 reg_number; \
|
||||
.uleb128 2f-1f; \
|
||||
1:.byte DW_OP_breg4; \
|
||||
.sleb128 offset; \
|
||||
2: \
|
||||
|
||||
ENTRY_PRIVATE(__restore)
|
||||
.L__restore_START:
|
||||
// This function must have exactly this instruction sequence for gdb and libunwind.
|
||||
// This function must have exactly this name for gdb.
|
||||
ENTRY(__restore)
|
||||
popl %eax
|
||||
movl $__NR_sigreturn, %eax
|
||||
int $0x80
|
||||
.L__restore_END:
|
||||
END(__restore)
|
||||
cfi_signal_frame_start(__restore)
|
||||
cfi_def_cfa(OFFSET_ESP + 4)
|
||||
cfi_offset(DW_x86_REG_EDI, OFFSET_EDI + 4)
|
||||
cfi_offset(DW_x86_REG_ESI, OFFSET_ESI + 4)
|
||||
cfi_offset(DW_x86_REG_EBP, OFFSET_EBP + 4)
|
||||
cfi_offset(DW_x86_REG_EBX, OFFSET_EBX + 4)
|
||||
cfi_offset(DW_x86_REG_EDX, OFFSET_EDX + 4)
|
||||
cfi_offset(DW_x86_REG_ECX, OFFSET_ECX + 4)
|
||||
cfi_offset(DW_x86_REG_EAX, OFFSET_EAX + 4)
|
||||
cfi_offset(DW_x86_REG_EIP, OFFSET_EIP + 4)
|
||||
cfi_signal_frame_end(__restore)
|
||||
|
||||
ENTRY_PRIVATE(__restore_rt)
|
||||
.L__restore_rt_START:
|
||||
movl $__NR_rt_sigreturn, %eax
|
||||
int $0x80
|
||||
.L__restore_rt_END:
|
||||
END(__restore_rt)
|
||||
cfi_signal_frame_start(__restore_rt)
|
||||
cfi_def_cfa(OFFSET_ESP + 160)
|
||||
cfi_offset(DW_x86_REG_EDI, OFFSET_EDI + 160)
|
||||
cfi_offset(DW_x86_REG_ESI, OFFSET_ESI + 160)
|
||||
cfi_offset(DW_x86_REG_EBP, OFFSET_EBP + 160)
|
||||
cfi_offset(DW_x86_REG_EBX, OFFSET_EBX + 160)
|
||||
cfi_offset(DW_x86_REG_EDX, OFFSET_EDX + 160)
|
||||
cfi_offset(DW_x86_REG_ECX, OFFSET_ECX + 160)
|
||||
cfi_offset(DW_x86_REG_EAX, OFFSET_EAX + 160)
|
||||
cfi_offset(DW_x86_REG_EIP, OFFSET_EIP + 160)
|
||||
cfi_signal_frame_end(__restore_rt)
|
||||
|
36
libc/arch-x86/bionic/__restore_rt.S
Normal file
36
libc/arch-x86/bionic/__restore_rt.S
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
// This function must have exactly this instruction sequence for gdb and libunwind.
|
||||
// This function must have exactly this name for gdb.
|
||||
ENTRY(__restore_rt)
|
||||
movl $__NR_rt_sigreturn, %eax
|
||||
int $0x80
|
||||
END(__restore_rt)
|
@@ -49,15 +49,6 @@
|
||||
#define PIC_GOT(x) x@GOT(%ebx)
|
||||
#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
|
||||
|
||||
/* let kernels and others override entrypoint alignment */
|
||||
#if !defined(_ALIGN_TEXT) && !defined(_KERNEL)
|
||||
# ifdef _STANDALONE
|
||||
# define _ALIGN_TEXT .align 1
|
||||
# elif defined __ELF__
|
||||
# define _ALIGN_TEXT .align 16
|
||||
# else
|
||||
# define _ALIGN_TEXT .align 4
|
||||
# endif
|
||||
#endif
|
||||
#define __bionic_asm_align 16
|
||||
|
||||
#endif /* !_I386_ASM_H_ */
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(clock_nanosleep)
|
||||
ENTRY(__clock_nanosleep)
|
||||
pushl %ebx
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset ebx, 0
|
||||
@@ -33,4 +33,4 @@ ENTRY(clock_nanosleep)
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
ret
|
||||
END(clock_nanosleep)
|
||||
END(__clock_nanosleep)
|
@@ -39,6 +39,7 @@ libc_bionic_src_files_x86 += \
|
||||
arch-x86/bionic/__bionic_clone.S \
|
||||
arch-x86/bionic/_exit_with_stack_teardown.S \
|
||||
arch-x86/bionic/libgcc_compat.c \
|
||||
arch-x86/bionic/__restore_rt.S \
|
||||
arch-x86/bionic/__restore.S \
|
||||
arch-x86/bionic/_setjmp.S \
|
||||
arch-x86/bionic/setjmp.S \
|
||||
|
@@ -28,116 +28,9 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
// DWARF constants.
|
||||
#define DW_CFA_def_cfa_expression 0x0f
|
||||
#define DW_CFA_expression 0x10
|
||||
#define DW_EH_PE_pcrel 0x10
|
||||
#define DW_EH_PE_sdata4 0x0b
|
||||
#define DW_OP_breg4 0x74
|
||||
#define DW_OP_breg7 0x77
|
||||
#define DW_OP_deref 0x06
|
||||
|
||||
// Offsets into struct ucontext_t of uc_mcontext.gregs[x].
|
||||
#define OFFSET_R8 40
|
||||
#define OFFSET_R9 48
|
||||
#define OFFSET_R10 56
|
||||
#define OFFSET_R11 64
|
||||
#define OFFSET_R12 72
|
||||
#define OFFSET_R13 80
|
||||
#define OFFSET_R14 88
|
||||
#define OFFSET_R15 96
|
||||
#define OFFSET_RDI 104
|
||||
#define OFFSET_RSI 112
|
||||
#define OFFSET_RBP 120
|
||||
#define OFFSET_RSP 160
|
||||
#define OFFSET_RBX 128
|
||||
#define OFFSET_RDX 136
|
||||
#define OFFSET_RAX 144
|
||||
#define OFFSET_RCX 152
|
||||
#define OFFSET_RIP 168
|
||||
|
||||
// Non-standard DWARF constants for the x86-64 registers.
|
||||
#define DW_x86_64_RAX 0
|
||||
#define DW_x86_64_RDX 1
|
||||
#define DW_x86_64_RCX 2
|
||||
#define DW_x86_64_RBX 3
|
||||
#define DW_x86_64_RSI 4
|
||||
#define DW_x86_64_RDI 5
|
||||
#define DW_x86_64_RBP 6
|
||||
#define DW_x86_64_RSP 7
|
||||
#define DW_x86_64_R8 8
|
||||
#define DW_x86_64_R9 9
|
||||
#define DW_x86_64_R10 10
|
||||
#define DW_x86_64_R11 11
|
||||
#define DW_x86_64_R12 12
|
||||
#define DW_x86_64_R13 13
|
||||
#define DW_x86_64_R14 14
|
||||
#define DW_x86_64_R15 15
|
||||
#define DW_x86_64_RIP 16
|
||||
|
||||
#define cfi_signal_frame_start(f) \
|
||||
.section .eh_frame,"a",@progbits; \
|
||||
.L ## f ## _START_EH_FRAME: \
|
||||
.long 2f - 1f; /* CIE length. */ \
|
||||
1:.long 0; /* CIE ID. */ \
|
||||
.byte 1; /* Version. */ \
|
||||
.string "zRS"; /* Augmentation string. */ \
|
||||
.uleb128 1; /* Code alignment factor. */ \
|
||||
.sleb128 -8; /* Data alignment factor. */ \
|
||||
.uleb128 DW_x86_64_RIP; /* Return address register. */ \
|
||||
.uleb128 1; /* 1 byte of augmentation data. */ \
|
||||
.byte (DW_EH_PE_pcrel | DW_EH_PE_sdata4); /* FDE encoding. */ \
|
||||
.align 8; \
|
||||
2: \
|
||||
.long .L ## f ## _END_FDE - .L ## f ## _START_FDE; /* FDE length. */ \
|
||||
.L ## f ## _START_FDE: \
|
||||
.long .L ## f ## _START_FDE - .L ## f ## _START_EH_FRAME; /* CIE location. */ \
|
||||
.long (.L ## f ## _START - 1) - .; /* pcrel start address (see FDE encoding above). */ \
|
||||
.long .L ## f ## _END - (.L ## f ## _START - 1); /* Function this FDE applies to. */ \
|
||||
.uleb128 0; /* FDE augmentation length. */ \
|
||||
|
||||
#define cfi_signal_frame_end(f) \
|
||||
.L ## f ## _END_FDE: \
|
||||
|
||||
#define cfi_def_cfa(offset) \
|
||||
.byte DW_CFA_def_cfa_expression; \
|
||||
.uleb128 2f-1f; \
|
||||
1:.byte DW_OP_breg7; \
|
||||
.sleb128 offset; \
|
||||
.byte DW_OP_deref; \
|
||||
2: \
|
||||
|
||||
#define cfi_offset(reg_number,offset) \
|
||||
.byte DW_CFA_expression; \
|
||||
.uleb128 reg_number; \
|
||||
.uleb128 2f-1f; \
|
||||
1:.byte DW_OP_breg7; \
|
||||
.sleb128 offset; \
|
||||
2: \
|
||||
|
||||
ENTRY_PRIVATE(__restore_rt)
|
||||
.L__restore_rt_START:
|
||||
// This function must have exactly this instruction sequence for gdb and libunwind.
|
||||
// This function must have exactly this name for gdb.
|
||||
ENTRY(__restore_rt)
|
||||
mov $__NR_rt_sigreturn, %rax
|
||||
syscall
|
||||
.L__restore_rt_END:
|
||||
END(__restore_rt)
|
||||
cfi_signal_frame_start(__restore_rt)
|
||||
cfi_def_cfa(OFFSET_RSP)
|
||||
cfi_offset(DW_x86_64_R8, OFFSET_R8)
|
||||
cfi_offset(DW_x86_64_R9, OFFSET_R9)
|
||||
cfi_offset(DW_x86_64_R10, OFFSET_R10)
|
||||
cfi_offset(DW_x86_64_R11, OFFSET_R11)
|
||||
cfi_offset(DW_x86_64_R12, OFFSET_R12)
|
||||
cfi_offset(DW_x86_64_R13, OFFSET_R13)
|
||||
cfi_offset(DW_x86_64_R14, OFFSET_R14)
|
||||
cfi_offset(DW_x86_64_R15, OFFSET_R15)
|
||||
cfi_offset(DW_x86_64_RDI, OFFSET_RDI)
|
||||
cfi_offset(DW_x86_64_RSI, OFFSET_RSI)
|
||||
cfi_offset(DW_x86_64_RBP, OFFSET_RBP)
|
||||
cfi_offset(DW_x86_64_RSP, OFFSET_RSP)
|
||||
cfi_offset(DW_x86_64_RBX, OFFSET_RBX)
|
||||
cfi_offset(DW_x86_64_RDX, OFFSET_RDX)
|
||||
cfi_offset(DW_x86_64_RAX, OFFSET_RAX)
|
||||
cfi_offset(DW_x86_64_RCX, OFFSET_RCX)
|
||||
cfi_offset(DW_x86_64_RIP, OFFSET_RIP)
|
||||
cfi_signal_frame_end(__restore_rt)
|
||||
|
@@ -40,13 +40,6 @@
|
||||
#define PIC_PLT(x) x@PLT
|
||||
#define PIC_GOT(x) x@GOTPCREL(%rip)
|
||||
|
||||
/* let kernels and others override entrypoint alignment */
|
||||
#ifndef _ALIGN_TEXT
|
||||
# ifdef _STANDALONE
|
||||
# define _ALIGN_TEXT .align 4
|
||||
# else
|
||||
# define _ALIGN_TEXT .align 16
|
||||
# endif
|
||||
#endif
|
||||
#define __bionic_asm_align 16
|
||||
|
||||
#endif /* !_AMD64_ASM_H_ */
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(clock_nanosleep)
|
||||
ENTRY(__clock_nanosleep)
|
||||
movq %rcx, %r10
|
||||
movl $__NR_clock_nanosleep, %eax
|
||||
syscall
|
||||
@@ -13,4 +13,5 @@ ENTRY(clock_nanosleep)
|
||||
call __set_errno_internal
|
||||
1:
|
||||
ret
|
||||
END(clock_nanosleep)
|
||||
END(__clock_nanosleep)
|
||||
.hidden __clock_nanosleep
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,16 +26,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BIONIC_PTHREAD_H
|
||||
#define _BIONIC_PTHREAD_H
|
||||
#define _GNU_SOURCE 1
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Internal, not an NDK API */
|
||||
extern pid_t __pthread_gettid(pthread_t thid);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _BIONIC_PTHREAD_H */
|
||||
extern "C" const char* __gnu_basename(const char* path) {
|
||||
const char* last_slash = strrchr(path, '/');
|
||||
return (last_slash != NULL) ? last_slash + 1 : path;
|
||||
}
|
107
libc/bionic/bionic_systrace.cpp
Normal file
107
libc/bionic/bionic_systrace.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <cutils/trace.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "private/bionic_systrace.h"
|
||||
#include "private/libc_logging.h"
|
||||
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
|
||||
#define WRITE_OFFSET 32
|
||||
|
||||
static const prop_info* g_pinfo = NULL;
|
||||
static uint32_t g_serial = -1;
|
||||
static uint64_t g_tags = 0;
|
||||
static int g_trace_marker_fd = -1;
|
||||
|
||||
static bool should_trace() {
|
||||
// If g_pinfo is null, this means that systrace hasn't been run and it's safe to
|
||||
// assume that no trace writing will need to take place. However, to avoid running
|
||||
// this costly find check each time, we set it to a non-tracing value so that next
|
||||
// time, it will just check the serial to see if the value has been changed.
|
||||
// this function also deals with the bootup case, during which the call to property
|
||||
// set will fail if the property server hasn't yet started.
|
||||
if (g_pinfo == NULL) {
|
||||
g_pinfo = __system_property_find("debug.atrace.tags.enableflags");
|
||||
if (g_pinfo == NULL) {
|
||||
__system_property_set("debug.atrace.tags.enableflags", "0");
|
||||
g_pinfo = __system_property_find("debug.atrace.tags.enableflags");
|
||||
if (g_pinfo == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find out which tags have been enabled on the command line and set
|
||||
// the value of tags accordingly. If the value of the property changes,
|
||||
// the serial will also change, so the costly system_property_read function
|
||||
// can be avoided by calling the much cheaper system_property_serial
|
||||
// first. The values within pinfo may change, but its location is guaranteed
|
||||
// not to move.
|
||||
const uint32_t cur_serial = __system_property_serial(g_pinfo);
|
||||
if (cur_serial != g_serial) {
|
||||
g_serial = cur_serial;
|
||||
char value[PROP_VALUE_MAX];
|
||||
__system_property_read(g_pinfo, 0, value);
|
||||
g_tags = strtoull(value, NULL, 0);
|
||||
}
|
||||
|
||||
// Finally, verify that this tag value enables bionic tracing.
|
||||
return ((g_tags & ATRACE_TAG_BIONIC) != 0);
|
||||
}
|
||||
|
||||
ScopedTrace::ScopedTrace(const char* message) {
|
||||
if (!should_trace()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_trace_marker_fd == -1) {
|
||||
g_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
|
||||
if (g_trace_marker_fd == -1) {
|
||||
__libc_fatal("Could not open kernel trace file: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// If bionic tracing has been enabled, then write the message to the
|
||||
// kernel trace_marker.
|
||||
int length = strlen(message);
|
||||
char buf[length + WRITE_OFFSET];
|
||||
size_t len = snprintf(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message);
|
||||
ssize_t wbytes = TEMP_FAILURE_RETRY(write(g_trace_marker_fd, buf, len));
|
||||
|
||||
// Error while writing
|
||||
if (static_cast<size_t>(wbytes) != len) {
|
||||
__libc_fatal("Could not write to kernel trace file: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
ScopedTrace::~ScopedTrace() {
|
||||
if (!should_trace()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssize_t wbytes = TEMP_FAILURE_RETRY(write(g_trace_marker_fd, "E", 1));
|
||||
|
||||
// Error while writing
|
||||
if (static_cast<size_t>(wbytes) != 1) {
|
||||
__libc_fatal("Could not write to kernel trace file: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "private/bionic_time_conversions.h"
|
||||
|
||||
#include "private/bionic_constants.h"
|
||||
|
||||
bool timespec_from_timeval(timespec& ts, const timeval& tv) {
|
||||
// Whole seconds can just be copied.
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
@@ -49,3 +51,19 @@ void timeval_from_timespec(timeval& tv, const timespec& ts) {
|
||||
tv.tv_sec = ts.tv_sec;
|
||||
tv.tv_usec = ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
// Initializes 'ts' with the difference between 'abs_ts' and the current time
|
||||
// according to 'clock'. Returns false if abstime already expired, true otherwise.
|
||||
bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock) {
|
||||
clock_gettime(clock, &ts);
|
||||
ts.tv_sec = abs_ts.tv_sec - ts.tv_sec;
|
||||
ts.tv_nsec = abs_ts.tv_nsec - ts.tv_nsec;
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_sec--;
|
||||
ts.tv_nsec += NS_PER_S;
|
||||
}
|
||||
if (ts.tv_nsec < 0 || ts.tv_sec < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include <sys/sysconf.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
#define NS_PER_S 1000000000 // No "private/bionic_constants.h" in lmp-dev.
|
||||
#include "private/bionic_constants.h"
|
||||
|
||||
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html
|
||||
clock_t clock() {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -25,40 +25,14 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _PATHCONF_H_
|
||||
#define _PATHCONF_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <time.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
#include "private/ErrnoRestorer.h"
|
||||
|
||||
/* constants to be used for the 'name' paremeter of pathconf/fpathconf */
|
||||
|
||||
#define _PC_FILESIZEBITS 0x0000
|
||||
#define _PC_LINK_MAX 0x0001
|
||||
#define _PC_MAX_CANON 0x0002
|
||||
#define _PC_MAX_INPUT 0x0003
|
||||
#define _PC_NAME_MAX 0x0004
|
||||
#define _PC_PATH_MAX 0x0005
|
||||
#define _PC_PIPE_BUF 0x0006
|
||||
#define _PC_2_SYMLINKS 0x0007
|
||||
#define _PC_ALLOC_SIZE_MIN 0x0008
|
||||
#define _PC_REC_INCR_XFER_SIZE 0x0009
|
||||
#define _PC_REC_MAX_XFER_SIZE 0x000a
|
||||
#define _PC_REC_MIN_XFER_SIZE 0x000b
|
||||
#define _PC_REC_XFER_ALIGN 0x000c
|
||||
#define _PC_SYMLINK_MAX 0x000d
|
||||
#define _PC_CHOWN_RESTRICTED 0x000e
|
||||
#define _PC_NO_TRUNC 0x000f
|
||||
#define _PC_VDISABLE 0x0010
|
||||
#define _PC_ASYNC_IO 0x0011
|
||||
#define _PC_PRIO_IO 0x0012
|
||||
#define _PC_SYNC_IO 0x0013
|
||||
|
||||
extern long fpathconf(int fildes, int name);
|
||||
extern long pathconf(const char *path, int name);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PATHCONF_H_ */
|
||||
extern "C" int __clock_nanosleep(clockid_t, int, const timespec*, timespec*);
|
||||
|
||||
int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) {
|
||||
ErrnoRestorer errno_restorer;
|
||||
return (__clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
|
||||
}
|
@@ -26,7 +26,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define __GNU_SOURCE 1
|
||||
#define _GNU_SOURCE 1
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@@ -71,7 +71,7 @@ __LIBC_HIDDEN__ mapinfo_t* mapinfo_create(pid_t pid) {
|
||||
struct mapinfo_t* milist = NULL;
|
||||
char data[1024]; // Used to read lines as well as to construct the filename.
|
||||
snprintf(data, sizeof(data), "/proc/%d/maps", pid);
|
||||
FILE* fp = fopen(data, "r");
|
||||
FILE* fp = fopen(data, "re");
|
||||
if (fp != NULL) {
|
||||
while (fgets(data, sizeof(data), fp) != NULL) {
|
||||
mapinfo_t* mi = parse_maps_line(data);
|
||||
|
@@ -78,7 +78,7 @@ DIR* fdopendir(int fd) {
|
||||
}
|
||||
|
||||
DIR* opendir(const char* path) {
|
||||
int fd = open(path, O_RDONLY | O_DIRECTORY);
|
||||
int fd = open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY);
|
||||
return (fd != -1) ? __allocate_DIR(fd) : NULL;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "dlmalloc.h"
|
||||
|
||||
#include "malloc.h"
|
||||
#include "private/bionic_prctl.h"
|
||||
#include "private/libc_logging.h"
|
||||
|
||||
@@ -54,3 +55,25 @@ static void* named_anonymous_mmap(size_t length) {
|
||||
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map, length, "libc_malloc");
|
||||
return map;
|
||||
}
|
||||
|
||||
// Since dlmalloc isn't the default, we'll leave this unimplemented for now. If
|
||||
// we decide we need it later, we can fill it in.
|
||||
size_t __mallinfo_narenas() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t __mallinfo_nbins() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mallinfo __mallinfo_arena_info(size_t aidx __unused) {
|
||||
struct mallinfo mi;
|
||||
memset(&mi, 0, sizeof(mi));
|
||||
return mi;
|
||||
}
|
||||
|
||||
struct mallinfo __mallinfo_bin_info(size_t aidx __unused, size_t bidx __unused) {
|
||||
struct mallinfo mi;
|
||||
memset(&mi, 0, sizeof(mi));
|
||||
return mi;
|
||||
}
|
||||
|
@@ -36,20 +36,12 @@
|
||||
// struct __sfileext (see fileext.h).
|
||||
|
||||
void flockfile(FILE* fp) {
|
||||
if (!__sdidinit) {
|
||||
__sinit();
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
pthread_mutex_lock(&_FLOCK(fp));
|
||||
}
|
||||
}
|
||||
|
||||
int ftrylockfile(FILE* fp) {
|
||||
if (!__sdidinit) {
|
||||
__sinit();
|
||||
}
|
||||
|
||||
// The specification for ftrylockfile() says it returns 0 on success,
|
||||
// or non-zero on error. So return an errno code directly on error.
|
||||
if (fp == NULL) {
|
||||
@@ -60,10 +52,6 @@ int ftrylockfile(FILE* fp) {
|
||||
}
|
||||
|
||||
void funlockfile(FILE* fp) {
|
||||
if (!__sdidinit) {
|
||||
__sinit();
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
pthread_mutex_unlock(&_FLOCK(fp));
|
||||
}
|
||||
|
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of KTH nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* $Heimdal: hash.h,v 1.1 1999/03/22 19:16:25 joda Exp $
|
||||
$NetBSD: hash.h,v 1.1.1.3 2002/09/12 12:41:42 joda Exp $ */
|
||||
|
||||
/* stuff in common between md4, md5, and sha1 */
|
||||
|
||||
#ifndef __hash_h__
|
||||
#define __hash_h__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a)>(b))?(b):(a))
|
||||
#endif
|
||||
|
||||
/* Vector Crays doesn't have a good 32-bit type, or more precisely,
|
||||
int32_t as defined by <bind/bitypes.h> isn't 32 bits, and we don't
|
||||
want to depend in being able to redefine this type. To cope with
|
||||
this we have to clamp the result in some places to [0,2^32); no
|
||||
need to do this on other machines. Did I say this was a mess?
|
||||
*/
|
||||
|
||||
#ifdef _CRAY
|
||||
#define CRAYFIX(X) ((X) & 0xffffffff)
|
||||
#else
|
||||
#define CRAYFIX(X) (X)
|
||||
#endif
|
||||
|
||||
static inline u_int32_t
|
||||
cshift (u_int32_t x, unsigned int n)
|
||||
{
|
||||
x = CRAYFIX(x);
|
||||
return CRAYFIX((x << n) | (x >> (32 - n)));
|
||||
}
|
||||
|
||||
#endif /* __hash_h__ */
|
@@ -17,11 +17,20 @@
|
||||
#include <ftw.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int mkstemp64(char* filename) {
|
||||
// Delegation will work in this case because all the transitive dependencies
|
||||
// are already 64-bit ready. In particular, we don't have non-O_LARGEFILE
|
||||
// open (our open is actually open64) and stat and stat64 are the same.
|
||||
return mkstemp(filename);
|
||||
// Delegation will work in these cases because all the transitive dependencies
|
||||
// are already 64-bit ready. In particular, we don't have non-O_LARGEFILE
|
||||
// open (our open is actually open64) and stat and stat64 are the same.
|
||||
int mkstemp64(char* path) {
|
||||
return mkstemp(path);
|
||||
}
|
||||
int mkostemp64(char* path, int flags) {
|
||||
return mkostemp(path, flags);
|
||||
}
|
||||
int mkstemps64(char* path, int suffix_length) {
|
||||
return mkstemps(path, suffix_length);
|
||||
}
|
||||
int mkostemps64(char* path, int suffix_length, int flags) {
|
||||
return mkostemps(path, suffix_length, flags);
|
||||
}
|
||||
|
||||
typedef int (*ftw_fn)(const char*, const struct stat*, int);
|
||||
|
@@ -49,7 +49,7 @@ extern "C" int __system_properties_init(void);
|
||||
extern "C" int __set_tls(void* ptr);
|
||||
extern "C" int __set_tid_address(int* tid_address);
|
||||
|
||||
void __libc_init_vdso();
|
||||
__LIBC_HIDDEN__ void __libc_init_vdso();
|
||||
|
||||
// Not public, but well-known in the BSDs.
|
||||
const char* __progname;
|
||||
|
@@ -75,10 +75,12 @@ struct BufferOutputStream {
|
||||
len = strlen(data);
|
||||
}
|
||||
|
||||
total += len;
|
||||
|
||||
while (len > 0) {
|
||||
int avail = end_ - pos_;
|
||||
if (avail == 0) {
|
||||
break;
|
||||
return;
|
||||
}
|
||||
if (avail > len) {
|
||||
avail = len;
|
||||
@@ -87,11 +89,10 @@ struct BufferOutputStream {
|
||||
pos_ += avail;
|
||||
pos_[0] = '\0';
|
||||
len -= avail;
|
||||
total += avail;
|
||||
}
|
||||
}
|
||||
|
||||
int total;
|
||||
size_t total;
|
||||
|
||||
private:
|
||||
char* buffer_;
|
||||
@@ -109,18 +110,19 @@ struct FdOutputStream {
|
||||
len = strlen(data);
|
||||
}
|
||||
|
||||
total += len;
|
||||
|
||||
while (len > 0) {
|
||||
int rc = TEMP_FAILURE_RETRY(write(fd_, data, len));
|
||||
if (rc == -1) {
|
||||
break;
|
||||
return;
|
||||
}
|
||||
data += rc;
|
||||
len -= rc;
|
||||
total += rc;
|
||||
}
|
||||
}
|
||||
|
||||
int total;
|
||||
size_t total;
|
||||
|
||||
private:
|
||||
int fd_;
|
||||
|
@@ -29,14 +29,13 @@
|
||||
// Contains definition of structures, global variables, and implementation of
|
||||
// routines that are used by malloc leak detection code and other components in
|
||||
// the system. The trick is that some components expect these data and
|
||||
// routines to be defined / implemented in libc.so library, regardless
|
||||
// whether or not MALLOC_LEAK_CHECK macro is defined. To make things even
|
||||
// more tricky, malloc leak detection code, implemented in
|
||||
// libc_malloc_debug.so also requires access to these variables and routines
|
||||
// (to fill allocation entry hash table, for example). So, all relevant
|
||||
// variables and routines are defined / implemented here and exported
|
||||
// to all, leak detection code and other components via dynamic (libc.so),
|
||||
// or static (libc.a) linking.
|
||||
// routines to be defined / implemented in libc.so, regardless whether or not
|
||||
// malloc leak detection code is going to run. To make things even more tricky,
|
||||
// malloc leak detection code, implemented in libc_malloc_debug.so also
|
||||
// requires access to these variables and routines (to fill allocation entry
|
||||
// hash table, for example). So, all relevant variables and routines are
|
||||
// defined / implemented here and exported to all, leak detection code and
|
||||
// other components via dynamic (libc.so), or static (libc.a) linking.
|
||||
|
||||
#include "malloc_debug_common.h"
|
||||
|
||||
|
@@ -55,13 +55,6 @@
|
||||
#include "private/libc_logging.h"
|
||||
#include "private/ScopedPthreadMutexLocker.h"
|
||||
|
||||
// This file should be included into the build only when
|
||||
// MALLOC_LEAK_CHECK, or MALLOC_QEMU_INSTRUMENT, or both
|
||||
// macros are defined.
|
||||
#ifndef MALLOC_LEAK_CHECK
|
||||
#error MALLOC_LEAK_CHECK is not defined.
|
||||
#endif // !MALLOC_LEAK_CHECK
|
||||
|
||||
extern int gMallocLeakZygoteChild;
|
||||
extern HashTable* g_hash_table;
|
||||
extern const MallocDebug* g_malloc_dispatch;
|
||||
|
@@ -606,7 +606,7 @@ extern "C" bool malloc_debug_initialize(HashTable*, const MallocDebug* malloc_di
|
||||
* the memory mapped spaces into writes to an I/O port that emulator
|
||||
* "listens to" on the other end. Note that until we open and map that
|
||||
* device, logging to emulator's stdout will not be available. */
|
||||
int fd = open("/dev/qemu_trace", O_RDWR);
|
||||
int fd = open("/dev/qemu_trace", O_CLOEXEC | O_RDWR);
|
||||
if (fd < 0) {
|
||||
error_log("Unable to open /dev/qemu_trace");
|
||||
return false;
|
||||
|
94
libc/bionic/malloc_info.cpp
Normal file
94
libc/bionic/malloc_info.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "malloc_info.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include "private/bionic_macros.h"
|
||||
|
||||
class __LIBC_HIDDEN__ Elem {
|
||||
public:
|
||||
// name must be valid throughout lifetime of the object.
|
||||
explicit Elem(FILE* fp, const char* name,
|
||||
const char* attr_fmt = nullptr, ...) {
|
||||
this->fp = fp;
|
||||
this->name = name;
|
||||
|
||||
fprintf(fp, "<%s", name);
|
||||
if (attr_fmt != nullptr) {
|
||||
va_list args;
|
||||
va_start(args, attr_fmt);
|
||||
fputc(' ', fp);
|
||||
vfprintf(fp, attr_fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
fputc('>', fp);
|
||||
}
|
||||
|
||||
~Elem() noexcept {
|
||||
fprintf(fp, "</%s>", name);
|
||||
}
|
||||
|
||||
void contents(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(fp, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
private:
|
||||
FILE* fp;
|
||||
const char* name;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Elem);
|
||||
};
|
||||
|
||||
int malloc_info(int options, FILE* fp) {
|
||||
if (options != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Elem root(fp, "malloc", "version=\"jemalloc-1\"");
|
||||
|
||||
// Dump all of the large allocations in the arenas.
|
||||
for (size_t i = 0; i < __mallinfo_narenas(); i++) {
|
||||
struct mallinfo mi = __mallinfo_arena_info(i);
|
||||
if (mi.hblkhd != 0) {
|
||||
Elem arena_elem(fp, "heap", "nr=\"%d\"", i);
|
||||
{
|
||||
Elem(fp, "allocated-large").contents("%zu", mi.ordblks);
|
||||
Elem(fp, "allocated-huge").contents("%zu", mi.uordblks);
|
||||
Elem(fp, "allocated-bins").contents("%zu", mi.fsmblks);
|
||||
|
||||
size_t total = 0;
|
||||
for (size_t j = 0; j < __mallinfo_nbins(); j++) {
|
||||
struct mallinfo mi = __mallinfo_bin_info(i, j);
|
||||
if (mi.ordblks != 0) {
|
||||
Elem bin_elem(fp, "bin", "nr=\"%d\"", j);
|
||||
Elem(fp, "allocated").contents("%zu", mi.ordblks);
|
||||
Elem(fp, "nmalloc").contents("%zu", mi.uordblks);
|
||||
Elem(fp, "ndalloc").contents("%zu", mi.fordblks);
|
||||
total += mi.ordblks;
|
||||
}
|
||||
}
|
||||
Elem(fp, "bins-total").contents("%zu", total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
32
libc/bionic/malloc_info.h
Normal file
32
libc/bionic/malloc_info.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef LIBC_BIONIC_MALLOC_INFO_H_
|
||||
#define LIBC_BIONIC_MALLOC_INFO_H_
|
||||
|
||||
#include <malloc.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
__LIBC_HIDDEN__ size_t __mallinfo_narenas();
|
||||
__LIBC_HIDDEN__ size_t __mallinfo_nbins();
|
||||
__LIBC_HIDDEN__ struct mallinfo __mallinfo_arena_info(size_t);
|
||||
__LIBC_HIDDEN__ struct mallinfo __mallinfo_bin_info(size_t, size_t);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // LIBC_BIONIC_MALLOC_INFO_H_
|
@@ -320,6 +320,11 @@ extern "C" size_t dlmalloc_usable_size(void* ptr) {
|
||||
return malloc_usable_size(ptr);
|
||||
}
|
||||
|
||||
// In L we added a public pthread_gettid_np, but some apps were using the private API.
|
||||
extern "C" pid_t __pthread_gettid(pthread_t t) {
|
||||
return pthread_gettid_np(t);
|
||||
}
|
||||
|
||||
// Older versions of appportable used dlmalloc directly instead of malloc,
|
||||
// so export this compatibility shim that simply calls malloc.
|
||||
extern "C" void* dlmalloc(size_t size) {
|
||||
|
@@ -38,11 +38,11 @@ void* operator new[](std::size_t size) {
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete(void* ptr) {
|
||||
void operator delete(void* ptr) throw() {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr) {
|
||||
void operator delete[](void* ptr) throw() {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
@@ -54,10 +54,10 @@ void* operator new[](std::size_t size, const std::nothrow_t&) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, const std::nothrow_t&) {
|
||||
void operator delete(void* ptr, const std::nothrow_t&) throw() {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr, const std::nothrow_t&) {
|
||||
void operator delete[](void* ptr, const std::nothrow_t&) throw() {
|
||||
free(ptr);
|
||||
}
|
||||
|
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <pathconf.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <sys/limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* these may not be defined yet by our headers */
|
||||
#ifndef _POSIX_VDISABLE
|
||||
#define _POSIX_VDISABLE -1
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_SYNC_IO
|
||||
#define _POSIX_SYNC_IO -1
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_PRIO_IO
|
||||
#define _POSIX_PRIO_IO -1
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_ASYNC_IO
|
||||
#define _POSIX_ASYNC_IO -1
|
||||
#endif
|
||||
|
||||
|
||||
static long
|
||||
__filesizebits( struct statfs* s )
|
||||
{
|
||||
#define EOL_MAGIC 0x0000U
|
||||
|
||||
/* list of known 64-bit aware filesystems */
|
||||
static const uint32_t known64[] = {
|
||||
EXT2_SUPER_MAGIC,
|
||||
UFS_MAGIC,
|
||||
REISERFS_SUPER_MAGIC,
|
||||
XFS_SUPER_MAGIC,
|
||||
SMB_SUPER_MAGIC,
|
||||
UDF_SUPER_MAGIC,
|
||||
JFS_SUPER_MAGIC,
|
||||
NTFS_SB_MAGIC,
|
||||
VXFS_SUPER_MAGIC,
|
||||
EOL_MAGIC
|
||||
};
|
||||
int nn = 0;
|
||||
|
||||
for (; known64[nn] != EOL_MAGIC; ++nn) {
|
||||
if (known64[nn] == s->f_type) {
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
return 32;
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
__link_max( struct statfs* s )
|
||||
{
|
||||
// These constant values were taken from kernel headers.
|
||||
// They're not available in uapi headers.
|
||||
static const struct { uint32_t type; int max; } knownMax[] =
|
||||
{
|
||||
{ EXT2_SUPER_MAGIC, 32000 },
|
||||
{ EXT3_SUPER_MAGIC, 32000 },
|
||||
{ MINIX_SUPER_MAGIC, 250 },
|
||||
{ MINIX2_SUPER_MAGIC, 65530 },
|
||||
{ REISERFS_SUPER_MAGIC, 0xffff - 1000 },
|
||||
{ UFS_MAGIC, 32000 },
|
||||
{ EOL_MAGIC, 0 }
|
||||
};
|
||||
int nn = 0;
|
||||
|
||||
for (; knownMax[nn].type != EOL_MAGIC; ++nn) {
|
||||
if (knownMax[nn].type == s->f_type) {
|
||||
return knownMax[nn].max;
|
||||
}
|
||||
}
|
||||
return LINK_MAX;
|
||||
}
|
||||
|
||||
static long
|
||||
__2_symlinks( struct statfs* s )
|
||||
{
|
||||
/* list of know filesystems that don't support symlinks */
|
||||
static const uint32_t knownNoSymlinks[] = {
|
||||
ADFS_SUPER_MAGIC, BFS_MAGIC, CRAMFS_MAGIC,
|
||||
EFS_SUPER_MAGIC, MSDOS_SUPER_MAGIC, NTFS_SB_MAGIC,
|
||||
QNX4_SUPER_MAGIC,
|
||||
EOL_MAGIC
|
||||
};
|
||||
int nn = 0;
|
||||
|
||||
for (; knownNoSymlinks[nn] != EOL_MAGIC; ++nn) {
|
||||
if (knownNoSymlinks[nn] == s->f_type) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long
|
||||
__name_max( struct statfs* s )
|
||||
{
|
||||
return s->f_namelen;
|
||||
}
|
||||
|
||||
long
|
||||
pathconf(const char *path, int name)
|
||||
{
|
||||
struct statfs buf;
|
||||
int ret = statfs( path, &buf );
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
switch (name) {
|
||||
case _PC_FILESIZEBITS:
|
||||
return __filesizebits(&buf);
|
||||
|
||||
case _PC_LINK_MAX:
|
||||
return __link_max(&buf);
|
||||
|
||||
case _PC_MAX_CANON:
|
||||
return MAX_CANON;
|
||||
|
||||
case _PC_MAX_INPUT:
|
||||
return MAX_INPUT;
|
||||
|
||||
case _PC_NAME_MAX:
|
||||
return __name_max(&buf);
|
||||
|
||||
case _PC_PATH_MAX:
|
||||
return PATH_MAX;
|
||||
|
||||
case _PC_PIPE_BUF:
|
||||
return PIPE_BUF;
|
||||
|
||||
case _PC_2_SYMLINKS:
|
||||
return __2_symlinks(&buf);
|
||||
|
||||
#if 0 /* don't know what to do there, the specs are really weird */
|
||||
case _PC_ALLOC_SIZE_MIN:
|
||||
case _PC_REC_INCR_XFER_SIZE:
|
||||
case _PC_REC_MAX_XFER_SIZE:
|
||||
case _PC_REC_MIN_XFER_SIZE:
|
||||
case _PC_REC_XFER_ALIGN:
|
||||
#endif
|
||||
|
||||
case _PC_SYMLINK_MAX:
|
||||
return -1; /* no limit */
|
||||
|
||||
case _PC_CHOWN_RESTRICTED:
|
||||
return _POSIX_CHOWN_RESTRICTED;
|
||||
|
||||
case _PC_NO_TRUNC:
|
||||
return _POSIX_NO_TRUNC;
|
||||
|
||||
case _PC_VDISABLE:
|
||||
return _POSIX_VDISABLE;
|
||||
|
||||
case _PC_ASYNC_IO:
|
||||
return _POSIX_ASYNC_IO;
|
||||
|
||||
case _PC_PRIO_IO:
|
||||
return _POSIX_PRIO_IO;
|
||||
|
||||
case _PC_SYNC_IO:
|
||||
return _POSIX_SYNC_IO;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long fpathconf(int fildes, int name)
|
||||
{
|
||||
struct statfs buf;
|
||||
int ret = fstatfs(fildes, &buf);
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
switch (name) {
|
||||
case _PC_FILESIZEBITS:
|
||||
return __filesizebits(&buf);
|
||||
|
||||
case _PC_LINK_MAX:
|
||||
return __link_max(&buf);
|
||||
|
||||
case _PC_MAX_CANON:
|
||||
return MAX_CANON;
|
||||
|
||||
case _PC_MAX_INPUT:
|
||||
return MAX_INPUT;
|
||||
|
||||
case _PC_NAME_MAX:
|
||||
return __name_max(&buf);
|
||||
|
||||
case _PC_PATH_MAX:
|
||||
return PATH_MAX;
|
||||
|
||||
case _PC_PIPE_BUF:
|
||||
return PIPE_BUF;
|
||||
|
||||
case _PC_2_SYMLINKS:
|
||||
return __2_symlinks(&buf);
|
||||
|
||||
#if 0 /* don't know what to do there, the specs are really weird */
|
||||
case _PC_ALLOC_SIZE_MIN:
|
||||
case _PC_REC_INCR_XFER_SIZE:
|
||||
case _PC_REC_MAX_XFER_SIZE:
|
||||
case _PC_REC_MIN_XFER_SIZE:
|
||||
case _PC_REC_XFER_ALIGN:
|
||||
#endif
|
||||
|
||||
case _PC_SYMLINK_MAX:
|
||||
return -1; /* no limit */
|
||||
|
||||
case _PC_CHOWN_RESTRICTED:
|
||||
return _POSIX_CHOWN_RESTRICTED;
|
||||
|
||||
case _PC_NO_TRUNC:
|
||||
return _POSIX_NO_TRUNC;
|
||||
|
||||
case _PC_VDISABLE:
|
||||
return _POSIX_VDISABLE;
|
||||
|
||||
case _PC_ASYNC_IO:
|
||||
return _POSIX_ASYNC_IO;
|
||||
|
||||
case _PC_PRIO_IO:
|
||||
return _POSIX_PRIO_IO;
|
||||
|
||||
case _PC_SYNC_IO:
|
||||
return _POSIX_SYNC_IO;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
152
libc/bionic/pathconf.cpp
Normal file
152
libc/bionic/pathconf.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
static long __filesizebits(const struct statfs& s) {
|
||||
switch (s.f_type) {
|
||||
case JFFS2_SUPER_MAGIC:
|
||||
case MSDOS_SUPER_MAGIC:
|
||||
case NCP_SUPER_MAGIC:
|
||||
return 32;
|
||||
}
|
||||
// There won't be any new 32-bit file systems.
|
||||
return 64;
|
||||
}
|
||||
|
||||
static long __link_max(const struct statfs& s) {
|
||||
// These constant values were taken from kernel headers.
|
||||
// They're not available in uapi headers.
|
||||
switch (s.f_type) {
|
||||
case EXT2_SUPER_MAGIC:
|
||||
return 32000;
|
||||
case MINIX_SUPER_MAGIC:
|
||||
return 250;
|
||||
case MINIX2_SUPER_MAGIC:
|
||||
return 65530;
|
||||
case REISERFS_SUPER_MAGIC:
|
||||
return 0xffff - 1000;
|
||||
case UFS_MAGIC:
|
||||
return 32000;
|
||||
}
|
||||
return LINK_MAX;
|
||||
}
|
||||
|
||||
static long __2_symlinks(const struct statfs& s) {
|
||||
switch (s.f_type) {
|
||||
case ADFS_SUPER_MAGIC:
|
||||
case BFS_MAGIC:
|
||||
case CRAMFS_MAGIC:
|
||||
case EFS_SUPER_MAGIC:
|
||||
case MSDOS_SUPER_MAGIC:
|
||||
case QNX4_SUPER_MAGIC:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long __pathconf(const struct statfs& s, int name) {
|
||||
switch (name) {
|
||||
case _PC_FILESIZEBITS:
|
||||
return __filesizebits(s);
|
||||
|
||||
case _PC_LINK_MAX:
|
||||
return __link_max(s);
|
||||
|
||||
case _PC_MAX_CANON:
|
||||
return MAX_CANON;
|
||||
|
||||
case _PC_MAX_INPUT:
|
||||
return MAX_INPUT;
|
||||
|
||||
case _PC_NAME_MAX:
|
||||
return s.f_namelen;
|
||||
|
||||
case _PC_PATH_MAX:
|
||||
return PATH_MAX;
|
||||
|
||||
case _PC_PIPE_BUF:
|
||||
return PIPE_BUF;
|
||||
|
||||
case _PC_2_SYMLINKS:
|
||||
return __2_symlinks(s);
|
||||
|
||||
#if 0
|
||||
case _PC_ALLOC_SIZE_MIN:
|
||||
case _PC_REC_INCR_XFER_SIZE:
|
||||
case _PC_REC_MAX_XFER_SIZE:
|
||||
case _PC_REC_MIN_XFER_SIZE:
|
||||
case _PC_REC_XFER_ALIGN:
|
||||
#endif
|
||||
|
||||
case _PC_SYMLINK_MAX:
|
||||
return -1; /* no limit */
|
||||
|
||||
case _PC_CHOWN_RESTRICTED:
|
||||
return _POSIX_CHOWN_RESTRICTED;
|
||||
|
||||
case _PC_NO_TRUNC:
|
||||
return _POSIX_NO_TRUNC;
|
||||
|
||||
case _PC_VDISABLE:
|
||||
return _POSIX_VDISABLE;
|
||||
|
||||
case _PC_ASYNC_IO:
|
||||
return -1;
|
||||
|
||||
case _PC_PRIO_IO:
|
||||
return -1;
|
||||
|
||||
case _PC_SYNC_IO:
|
||||
return -1;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long pathconf(const char* path, int name) {
|
||||
struct statfs sb;
|
||||
if (statfs(path, &sb) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return __pathconf(sb, name);
|
||||
}
|
||||
|
||||
long fpathconf(int fd, int name) {
|
||||
struct statfs sb;
|
||||
if (fstatfs(fd, &sb) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return __pathconf(sb, name);
|
||||
}
|
@@ -62,7 +62,6 @@ struct PosixTimer {
|
||||
pthread_t callback_thread;
|
||||
void (*callback)(sigval_t);
|
||||
sigval_t callback_argument;
|
||||
volatile bool armed;
|
||||
};
|
||||
|
||||
static __kernel_timer_t to_kernel_timer_id(timer_t timer) {
|
||||
@@ -84,7 +83,7 @@ static void* __timer_thread_start(void* arg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (si.si_code == SI_TIMER && timer->armed) {
|
||||
if (si.si_code == SI_TIMER) {
|
||||
// This signal was sent because a timer fired, so call the callback.
|
||||
timer->callback(timer->callback_argument);
|
||||
} else if (si.si_code == SI_TKILL) {
|
||||
@@ -96,9 +95,6 @@ static void* __timer_thread_start(void* arg) {
|
||||
}
|
||||
|
||||
static void __timer_thread_stop(PosixTimer* timer) {
|
||||
// Immediately mark the timer as disarmed so even if some events
|
||||
// continue to happen, the callback won't be called.
|
||||
timer->armed = false;
|
||||
pthread_kill(timer->callback_thread, TIMER_SIGNAL);
|
||||
}
|
||||
|
||||
@@ -125,7 +121,6 @@ int timer_create(clockid_t clock_id, sigevent* evp, timer_t* timer_id) {
|
||||
// Otherwise, this must be SIGEV_THREAD timer...
|
||||
timer->callback = evp->sigev_notify_function;
|
||||
timer->callback_argument = evp->sigev_value;
|
||||
timer->armed = false;
|
||||
|
||||
// Check arguments that the kernel doesn't care about but we do.
|
||||
if (timer->callback == NULL) {
|
||||
@@ -205,18 +200,7 @@ int timer_gettime(timer_t id, itimerspec* ts) {
|
||||
|
||||
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_getoverrun.html
|
||||
int timer_settime(timer_t id, int flags, const itimerspec* ts, itimerspec* ots) {
|
||||
PosixTimer* timer= reinterpret_cast<PosixTimer*>(id);
|
||||
int rc = __timer_settime(timer->kernel_timer_id, flags, ts, ots);
|
||||
if (rc == 0) {
|
||||
// Mark the timer as either being armed or disarmed. This avoids the
|
||||
// callback being called after the disarm for SIGEV_THREAD timers only.
|
||||
if (ts->it_value.tv_sec != 0 || ts->it_value.tv_nsec != 0) {
|
||||
timer->armed = true;
|
||||
} else {
|
||||
timer->armed = false;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return __timer_settime(to_kernel_timer_id(id), flags, ts, ots);
|
||||
}
|
||||
|
||||
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_getoverrun.html
|
||||
|
@@ -163,12 +163,12 @@ int __pthread_cond_timedwait_relative(pthread_cond_t* cond, pthread_mutex_t* mut
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__
|
||||
int __pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime, clockid_t clock) {
|
||||
int __pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abs_ts, clockid_t clock) {
|
||||
timespec ts;
|
||||
timespec* tsp;
|
||||
|
||||
if (abstime != NULL) {
|
||||
if (__timespec_from_absolute(&ts, abstime, clock) < 0) {
|
||||
if (abs_ts != NULL) {
|
||||
if (!timespec_from_absolute_timespec(ts, *abs_ts, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
tsp = &ts;
|
||||
|
@@ -27,13 +27,7 @@
|
||||
*/
|
||||
|
||||
#include "pthread_internal.h"
|
||||
#include "private/bionic_pthread.h"
|
||||
|
||||
pid_t pthread_gettid_np(pthread_t t) {
|
||||
return reinterpret_cast<pthread_internal_t*>(t)->tid;
|
||||
}
|
||||
|
||||
// TODO: move callers over to pthread_gettid_np and remove this.
|
||||
pid_t __pthread_gettid(pthread_t t) {
|
||||
return pthread_gettid_np(t);
|
||||
}
|
||||
|
@@ -117,8 +117,6 @@ __LIBC_HIDDEN__ void _pthread_internal_remove_locked(pthread_internal_t* thread)
|
||||
__LIBC_HIDDEN__ extern pthread_internal_t* g_thread_list;
|
||||
__LIBC_HIDDEN__ extern pthread_mutex_t g_thread_list_lock;
|
||||
|
||||
__LIBC_HIDDEN__ int __timespec_from_absolute(timespec*, const timespec*, clockid_t);
|
||||
|
||||
/* Needed by fork. */
|
||||
__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
|
||||
__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
|
||||
|
@@ -67,19 +67,3 @@ void _pthread_internal_add(pthread_internal_t* thread) {
|
||||
pthread_internal_t* __get_thread(void) {
|
||||
return reinterpret_cast<pthread_internal_t*>(__get_tls()[TLS_SLOT_THREAD_ID]);
|
||||
}
|
||||
|
||||
// Initialize 'ts' with the difference between 'abstime' and the current time
|
||||
// according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise.
|
||||
int __timespec_from_absolute(timespec* ts, const timespec* abstime, clockid_t clock) {
|
||||
clock_gettime(clock, ts);
|
||||
ts->tv_sec = abstime->tv_sec - ts->tv_sec;
|
||||
ts->tv_nsec = abstime->tv_nsec - ts->tv_nsec;
|
||||
if (ts->tv_nsec < 0) {
|
||||
ts->tv_sec--;
|
||||
ts->tv_nsec += 1000000000;
|
||||
}
|
||||
if ((ts->tv_nsec < 0) || (ts->tv_sec < 0)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -36,9 +36,13 @@
|
||||
#include "pthread_internal.h"
|
||||
|
||||
#include "private/bionic_atomic_inline.h"
|
||||
#include "private/bionic_constants.h"
|
||||
#include "private/bionic_futex.h"
|
||||
#include "private/bionic_time_conversions.h"
|
||||
#include "private/bionic_tls.h"
|
||||
|
||||
#include "private/bionic_systrace.h"
|
||||
|
||||
extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex);
|
||||
extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex);
|
||||
|
||||
@@ -333,6 +337,10 @@ static inline void _normal_lock(pthread_mutex_t* mutex, int shared) {
|
||||
* that the mutex is in state 2 when we go to sleep on it, which
|
||||
* guarantees a wake-up call.
|
||||
*/
|
||||
|
||||
ScopedTrace trace("Contending for pthread mutex");
|
||||
|
||||
|
||||
while (__bionic_swap(locked_contended, &mutex->value) != unlocked) {
|
||||
__futex_wait_ex(&mutex->value, shared, locked_contended, NULL);
|
||||
}
|
||||
@@ -440,12 +448,6 @@ static inline __always_inline int _recursive_increment(pthread_mutex_t* mutex, i
|
||||
}
|
||||
|
||||
int pthread_mutex_lock(pthread_mutex_t* mutex) {
|
||||
#if !defined(__LP64__)
|
||||
if (mutex == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int mvalue, mtype, tid, shared;
|
||||
|
||||
mvalue = mutex->value;
|
||||
@@ -479,6 +481,8 @@ int pthread_mutex_lock(pthread_mutex_t* mutex) {
|
||||
mvalue = mutex->value;
|
||||
}
|
||||
|
||||
ScopedTrace trace("Contending for pthread mutex");
|
||||
|
||||
for (;;) {
|
||||
int newval;
|
||||
|
||||
@@ -522,12 +526,6 @@ int pthread_mutex_lock(pthread_mutex_t* mutex) {
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock(pthread_mutex_t* mutex) {
|
||||
#if !defined(__LP64__)
|
||||
if (mutex == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int mvalue, mtype, tid, shared;
|
||||
|
||||
mvalue = mutex->value;
|
||||
@@ -619,7 +617,7 @@ int pthread_mutex_trylock(pthread_mutex_t* mutex) {
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs_timeout, clockid_t clock) {
|
||||
static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs_ts, clockid_t clock) {
|
||||
timespec ts;
|
||||
|
||||
int mvalue = mutex->value;
|
||||
@@ -638,9 +636,11 @@ static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScopedTrace trace("Contending for timed pthread mutex");
|
||||
|
||||
// Loop while needed.
|
||||
while (__bionic_swap(locked_contended, &mutex->value) != unlocked) {
|
||||
if (__timespec_from_absolute(&ts, abs_timeout, clock) < 0) {
|
||||
if (!timespec_from_absolute_timespec(ts, *abs_ts, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
__futex_wait_ex(&mutex->value, shared, locked_contended, &ts);
|
||||
@@ -670,6 +670,8 @@ static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs
|
||||
mvalue = mutex->value;
|
||||
}
|
||||
|
||||
ScopedTrace trace("Contending for timed pthread mutex");
|
||||
|
||||
while (true) {
|
||||
// If the value is 'unlocked', try to acquire it directly.
|
||||
// NOTE: put state to 2 since we know there is contention.
|
||||
@@ -681,7 +683,7 @@ static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs
|
||||
}
|
||||
// The value changed before we could lock it. We need to check
|
||||
// the time to avoid livelocks, reload the value, then loop again.
|
||||
if (__timespec_from_absolute(&ts, abs_timeout, clock) < 0) {
|
||||
if (!timespec_from_absolute_timespec(ts, *abs_ts, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -703,7 +705,7 @@ static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs
|
||||
}
|
||||
|
||||
// Check time and update 'ts'.
|
||||
if (__timespec_from_absolute(&ts, abs_timeout, clock) < 0) {
|
||||
if (timespec_from_absolute_timespec(ts, *abs_ts, clock)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -726,9 +728,9 @@ extern "C" int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex, unsigned ms
|
||||
clock_gettime(CLOCK_MONOTONIC, &abs_timeout);
|
||||
abs_timeout.tv_sec += ms / 1000;
|
||||
abs_timeout.tv_nsec += (ms % 1000) * 1000000;
|
||||
if (abs_timeout.tv_nsec >= 1000000000) {
|
||||
if (abs_timeout.tv_nsec >= NS_PER_S) {
|
||||
abs_timeout.tv_sec++;
|
||||
abs_timeout.tv_nsec -= 1000000000;
|
||||
abs_timeout.tv_nsec -= NS_PER_S;
|
||||
}
|
||||
|
||||
int error = __pthread_mutex_timedlock(mutex, &abs_timeout, CLOCK_MONOTONIC);
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "pthread_internal.h"
|
||||
#include "private/bionic_futex.h"
|
||||
#include "private/bionic_time_conversions.h"
|
||||
|
||||
/* Technical note:
|
||||
*
|
||||
@@ -71,7 +72,7 @@ static inline bool rwlock_is_shared(const pthread_rwlock_t* rwlock) {
|
||||
|
||||
static bool timespec_from_absolute(timespec* rel_timeout, const timespec* abs_timeout) {
|
||||
if (abs_timeout != NULL) {
|
||||
if (__timespec_from_absolute(rel_timeout, abs_timeout, CLOCK_REALTIME) < 0) {
|
||||
if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout, CLOCK_REALTIME)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -67,7 +67,7 @@ int pthread_setname_np(pthread_t t, const char* thread_name) {
|
||||
}
|
||||
char comm_name[sizeof(TASK_COMM_FMT) + 8];
|
||||
snprintf(comm_name, sizeof(comm_name), TASK_COMM_FMT, tid);
|
||||
int fd = open(comm_name, O_WRONLY);
|
||||
int fd = open(comm_name, O_CLOEXEC | O_WRONLY);
|
||||
if (fd == -1) {
|
||||
return errno;
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ void pututline(struct utmp* utmp)
|
||||
struct utmp u;
|
||||
long i;
|
||||
|
||||
if (!(f = fopen(_PATH_UTMP, "w+")))
|
||||
if (!(f = fopen(_PATH_UTMP, "w+e")))
|
||||
return;
|
||||
|
||||
while (fread(&u, sizeof(struct utmp), 1, f) == 1)
|
||||
@@ -55,7 +55,7 @@ void pututline(struct utmp* utmp)
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (!(f = fopen(_PATH_UTMP, "w+")))
|
||||
if (!(f = fopen(_PATH_UTMP, "w+e")))
|
||||
return;
|
||||
fwrite(utmp, sizeof(struct utmp), 1, f);
|
||||
|
||||
|
@@ -1,398 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "private/bionic_atomic_inline.h"
|
||||
#include "private/bionic_futex.h"
|
||||
|
||||
/* In this implementation, a semaphore contains a
|
||||
* 31-bit signed value and a 1-bit 'shared' flag
|
||||
* (for process-sharing purpose).
|
||||
*
|
||||
* We use the value -1 to indicate contention on the
|
||||
* semaphore, 0 or more to indicate uncontended state,
|
||||
* any value lower than -2 is invalid at runtime.
|
||||
*
|
||||
* State diagram:
|
||||
*
|
||||
* post(1) ==> 2
|
||||
* post(0) ==> 1
|
||||
* post(-1) ==> 1, then wake all waiters
|
||||
*
|
||||
* wait(2) ==> 1
|
||||
* wait(1) ==> 0
|
||||
* wait(0) ==> -1 then wait for a wake up + loop
|
||||
* wait(-1) ==> -1 then wait for a wake up + loop
|
||||
*
|
||||
*/
|
||||
|
||||
/* Use the upper 31-bits for the counter, and the lower one
|
||||
* for the shared flag.
|
||||
*/
|
||||
#define SEMCOUNT_SHARED_MASK 0x00000001
|
||||
#define SEMCOUNT_VALUE_MASK 0xfffffffe
|
||||
#define SEMCOUNT_VALUE_SHIFT 1
|
||||
|
||||
/* Maximum unsigned value that can be stored in the semaphore.
|
||||
* One bit is used for the shared flag, another one for the
|
||||
* sign bit, leaving us with only 30 bits.
|
||||
*/
|
||||
#define SEM_MAX_VALUE 0x3fffffff
|
||||
|
||||
/* convert a value into the corresponding sem->count bit pattern */
|
||||
#define SEMCOUNT_FROM_VALUE(val) (((val) << SEMCOUNT_VALUE_SHIFT) & SEMCOUNT_VALUE_MASK)
|
||||
|
||||
/* convert a sem->count bit pattern into the corresponding signed value */
|
||||
#define SEMCOUNT_TO_VALUE(sval) ((int)(sval) >> SEMCOUNT_VALUE_SHIFT)
|
||||
|
||||
/* the value +1 as a sem->count bit-pattern. */
|
||||
#define SEMCOUNT_ONE SEMCOUNT_FROM_VALUE(1)
|
||||
|
||||
/* the value -1 as a sem->count bit-pattern. */
|
||||
#define SEMCOUNT_MINUS_ONE SEMCOUNT_FROM_VALUE(-1)
|
||||
|
||||
#define SEMCOUNT_DECREMENT(sval) (((sval) - (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
|
||||
#define SEMCOUNT_INCREMENT(sval) (((sval) + (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
|
||||
|
||||
/* return the shared bitflag from a semaphore */
|
||||
#define SEM_GET_SHARED(sem) ((sem)->count & SEMCOUNT_SHARED_MASK)
|
||||
|
||||
|
||||
int sem_init(sem_t *sem, int pshared, unsigned int value)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ensure that 'value' can be stored in the semaphore */
|
||||
if (value > SEM_MAX_VALUE) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sem->count = SEMCOUNT_FROM_VALUE(value);
|
||||
if (pshared != 0)
|
||||
sem->count |= SEMCOUNT_SHARED_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sem_destroy(sem_t *sem)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (sem == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
count = SEMCOUNT_TO_VALUE(sem->count);
|
||||
if (count < 0) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
sem->count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sem_t *sem_open(const char *name __unused, int oflag __unused, ...)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return SEM_FAILED;
|
||||
}
|
||||
|
||||
|
||||
int sem_close(sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int sem_unlink(const char* name __unused)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Decrement a semaphore's value atomically,
|
||||
* and return the old one. As a special case,
|
||||
* this returns immediately if the value is
|
||||
* negative (i.e. -1)
|
||||
*/
|
||||
static int
|
||||
__sem_dec(volatile unsigned int *pvalue)
|
||||
{
|
||||
unsigned int shared = (*pvalue & SEMCOUNT_SHARED_MASK);
|
||||
unsigned int old, new;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old = (*pvalue & SEMCOUNT_VALUE_MASK);
|
||||
ret = SEMCOUNT_TO_VALUE(old);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
new = SEMCOUNT_DECREMENT(old);
|
||||
}
|
||||
while (__bionic_cmpxchg((int)(old|shared),
|
||||
(int)(new|shared),
|
||||
(volatile int *)pvalue) != 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Same as __sem_dec, but will not touch anything if the
|
||||
* value is already negative *or* 0. Returns the old value.
|
||||
*/
|
||||
static int
|
||||
__sem_trydec(volatile unsigned int *pvalue)
|
||||
{
|
||||
unsigned int shared = (*pvalue & SEMCOUNT_SHARED_MASK);
|
||||
unsigned int old, new;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old = (*pvalue & SEMCOUNT_VALUE_MASK);
|
||||
ret = SEMCOUNT_TO_VALUE(old);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
new = SEMCOUNT_DECREMENT(old);
|
||||
}
|
||||
while (__bionic_cmpxchg((int)(old|shared),
|
||||
(int)(new|shared),
|
||||
(volatile int *)pvalue) != 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* "Increment" the value of a semaphore atomically and
|
||||
* return its old value. Note that this implements
|
||||
* the special case of "incrementing" any negative
|
||||
* value to +1 directly.
|
||||
*
|
||||
* NOTE: The value will _not_ wrap above SEM_VALUE_MAX
|
||||
*/
|
||||
static int
|
||||
__sem_inc(volatile unsigned int *pvalue)
|
||||
{
|
||||
unsigned int shared = (*pvalue & SEMCOUNT_SHARED_MASK);
|
||||
unsigned int old, new;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old = (*pvalue & SEMCOUNT_VALUE_MASK);
|
||||
ret = SEMCOUNT_TO_VALUE(old);
|
||||
|
||||
/* Can't go higher than SEM_MAX_VALUE */
|
||||
if (ret == SEM_MAX_VALUE)
|
||||
break;
|
||||
|
||||
/* If the counter is negative, go directly to +1,
|
||||
* otherwise just increment */
|
||||
if (ret < 0)
|
||||
new = SEMCOUNT_ONE;
|
||||
else
|
||||
new = SEMCOUNT_INCREMENT(old);
|
||||
}
|
||||
while ( __bionic_cmpxchg((int)(old|shared),
|
||||
(int)(new|shared),
|
||||
(volatile int*)pvalue) != 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* lock a semaphore */
|
||||
int sem_wait(sem_t *sem)
|
||||
{
|
||||
unsigned shared;
|
||||
|
||||
if (sem == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
shared = SEM_GET_SHARED(sem);
|
||||
|
||||
for (;;) {
|
||||
if (__sem_dec(&sem->count) > 0)
|
||||
break;
|
||||
|
||||
__futex_wait_ex(&sem->count, shared, shared|SEMCOUNT_MINUS_ONE, NULL);
|
||||
}
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
|
||||
{
|
||||
unsigned int shared;
|
||||
|
||||
if (sem == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* POSIX says we need to try to decrement the semaphore
|
||||
* before checking the timeout value. Note that if the
|
||||
* value is currently 0, __sem_trydec() does nothing.
|
||||
*/
|
||||
if (__sem_trydec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check it as per Posix */
|
||||
if (abs_timeout == NULL ||
|
||||
abs_timeout->tv_sec < 0 ||
|
||||
abs_timeout->tv_nsec < 0 ||
|
||||
abs_timeout->tv_nsec >= 1000000000)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
shared = SEM_GET_SHARED(sem);
|
||||
|
||||
for (;;) {
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
|
||||
/* Posix mandates CLOCK_REALTIME here */
|
||||
clock_gettime( CLOCK_REALTIME, &ts );
|
||||
ts.tv_sec = abs_timeout->tv_sec - ts.tv_sec;
|
||||
ts.tv_nsec = abs_timeout->tv_nsec - ts.tv_nsec;
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1000000000;
|
||||
ts.tv_sec -= 1;
|
||||
}
|
||||
|
||||
if (ts.tv_sec < 0 || ts.tv_nsec < 0) {
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try to grab the semaphore. If the value was 0, this
|
||||
* will also change it to -1 */
|
||||
if (__sem_dec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Contention detected. wait for a wakeup event */
|
||||
ret = __futex_wait_ex(&sem->count, shared, shared|SEMCOUNT_MINUS_ONE, &ts);
|
||||
|
||||
/* return in case of timeout or interrupt */
|
||||
if (ret == -ETIMEDOUT || ret == -EINTR) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock a semaphore */
|
||||
int sem_post(sem_t *sem)
|
||||
{
|
||||
unsigned int shared;
|
||||
int old;
|
||||
|
||||
if (sem == NULL)
|
||||
return EINVAL;
|
||||
|
||||
shared = SEM_GET_SHARED(sem);
|
||||
|
||||
ANDROID_MEMBAR_FULL();
|
||||
old = __sem_inc(&sem->count);
|
||||
if (old < 0) {
|
||||
/* contention on the semaphore, wake up all waiters */
|
||||
__futex_wake_ex(&sem->count, shared, INT_MAX);
|
||||
}
|
||||
else if (old == SEM_MAX_VALUE) {
|
||||
/* overflow detected */
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_trywait(sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__sem_trydec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
} else {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that Posix requires that sem_getvalue() returns, in
|
||||
* case of contention, the negative of the number of waiting
|
||||
* threads.
|
||||
*
|
||||
* However, code that depends on this negative value to be
|
||||
* meaningful is most probably racy. The GLibc sem_getvalue()
|
||||
* only returns the semaphore value, which is 0, in case of
|
||||
* contention, so we will mimick this behaviour here instead
|
||||
* for better compatibility.
|
||||
*/
|
||||
int sem_getvalue(sem_t *sem, int *sval)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (sem == NULL || sval == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = SEMCOUNT_TO_VALUE(sem->count);
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
|
||||
*sval = val;
|
||||
return 0;
|
||||
}
|
289
libc/bionic/semaphore.cpp
Normal file
289
libc/bionic/semaphore.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "private/bionic_atomic_inline.h"
|
||||
#include "private/bionic_constants.h"
|
||||
#include "private/bionic_futex.h"
|
||||
#include "private/bionic_time_conversions.h"
|
||||
|
||||
// In this implementation, a semaphore contains a
|
||||
// 31-bit signed value and a 1-bit 'shared' flag
|
||||
// (for process-sharing purpose).
|
||||
//
|
||||
// We use the value -1 to indicate contention on the
|
||||
// semaphore, 0 or more to indicate uncontended state,
|
||||
// any value lower than -2 is invalid at runtime.
|
||||
//
|
||||
// State diagram:
|
||||
//
|
||||
// post(1) ==> 2
|
||||
// post(0) ==> 1
|
||||
// post(-1) ==> 1, then wake all waiters
|
||||
//
|
||||
// wait(2) ==> 1
|
||||
// wait(1) ==> 0
|
||||
// wait(0) ==> -1 then wait for a wake up + loop
|
||||
// wait(-1) ==> -1 then wait for a wake up + loop
|
||||
|
||||
// Use the upper 31-bits for the counter, and the lower one
|
||||
// for the shared flag.
|
||||
#define SEMCOUNT_SHARED_MASK 0x00000001
|
||||
#define SEMCOUNT_VALUE_MASK 0xfffffffe
|
||||
#define SEMCOUNT_VALUE_SHIFT 1
|
||||
|
||||
// Convert a value into the corresponding sem->count bit pattern.
|
||||
#define SEMCOUNT_FROM_VALUE(val) (((val) << SEMCOUNT_VALUE_SHIFT) & SEMCOUNT_VALUE_MASK)
|
||||
|
||||
// Convert a sem->count bit pattern into the corresponding signed value.
|
||||
static inline int SEMCOUNT_TO_VALUE(uint32_t sval) {
|
||||
return (static_cast<int>(sval) >> SEMCOUNT_VALUE_SHIFT);
|
||||
}
|
||||
|
||||
// The value +1 as a sem->count bit-pattern.
|
||||
#define SEMCOUNT_ONE SEMCOUNT_FROM_VALUE(1)
|
||||
|
||||
// The value -1 as a sem->count bit-pattern.
|
||||
#define SEMCOUNT_MINUS_ONE SEMCOUNT_FROM_VALUE(-1)
|
||||
|
||||
#define SEMCOUNT_DECREMENT(sval) (((sval) - (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
|
||||
#define SEMCOUNT_INCREMENT(sval) (((sval) + (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
|
||||
|
||||
// Return the shared bitflag from a semaphore.
|
||||
static inline uint32_t SEM_GET_SHARED(sem_t* sem) {
|
||||
return (sem->count & SEMCOUNT_SHARED_MASK);
|
||||
}
|
||||
|
||||
|
||||
int sem_init(sem_t* sem, int pshared, unsigned int value) {
|
||||
// Ensure that 'value' can be stored in the semaphore.
|
||||
if (value > SEM_VALUE_MAX) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sem->count = SEMCOUNT_FROM_VALUE(value);
|
||||
if (pshared != 0) {
|
||||
sem->count |= SEMCOUNT_SHARED_MASK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_destroy(sem_t*) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sem_t* sem_open(const char*, int, ...) {
|
||||
errno = ENOSYS;
|
||||
return SEM_FAILED;
|
||||
}
|
||||
|
||||
int sem_close(sem_t*) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sem_unlink(const char*) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Decrement a semaphore's value atomically,
|
||||
// and return the old one. As a special case,
|
||||
// this returns immediately if the value is
|
||||
// negative (i.e. -1)
|
||||
static int __sem_dec(volatile uint32_t* sem) {
|
||||
volatile int32_t* ptr = reinterpret_cast<volatile int32_t*>(sem);
|
||||
uint32_t shared = (*sem & SEMCOUNT_SHARED_MASK);
|
||||
uint32_t old_value, new_value;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old_value = (*sem & SEMCOUNT_VALUE_MASK);
|
||||
ret = SEMCOUNT_TO_VALUE(old_value);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
new_value = SEMCOUNT_DECREMENT(old_value);
|
||||
} while (__bionic_cmpxchg((old_value|shared), (new_value|shared), ptr) != 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Same as __sem_dec, but will not touch anything if the
|
||||
// value is already negative *or* 0. Returns the old value.
|
||||
static int __sem_trydec(volatile uint32_t* sem) {
|
||||
volatile int32_t* ptr = reinterpret_cast<volatile int32_t*>(sem);
|
||||
uint32_t shared = (*sem & SEMCOUNT_SHARED_MASK);
|
||||
uint32_t old_value, new_value;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old_value = (*sem & SEMCOUNT_VALUE_MASK);
|
||||
ret = SEMCOUNT_TO_VALUE(old_value);
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
new_value = SEMCOUNT_DECREMENT(old_value);
|
||||
} while (__bionic_cmpxchg((old_value|shared), (new_value|shared), ptr) != 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// "Increment" the value of a semaphore atomically and
|
||||
// return its old value. Note that this implements
|
||||
// the special case of "incrementing" any negative
|
||||
// value to +1 directly.
|
||||
//
|
||||
// NOTE: The value will _not_ wrap above SEM_VALUE_MAX
|
||||
static int __sem_inc(volatile uint32_t* sem) {
|
||||
volatile int32_t* ptr = reinterpret_cast<volatile int32_t*>(sem);
|
||||
uint32_t shared = (*sem & SEMCOUNT_SHARED_MASK);
|
||||
uint32_t old_value, new_value;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old_value = (*sem & SEMCOUNT_VALUE_MASK);
|
||||
ret = SEMCOUNT_TO_VALUE(old_value);
|
||||
|
||||
// Can't go higher than SEM_VALUE_MAX.
|
||||
if (ret == SEM_VALUE_MAX) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If the counter is negative, go directly to +1, otherwise just increment.
|
||||
if (ret < 0) {
|
||||
new_value = SEMCOUNT_ONE;
|
||||
} else {
|
||||
new_value = SEMCOUNT_INCREMENT(old_value);
|
||||
}
|
||||
} while (__bionic_cmpxchg((old_value|shared), (new_value|shared), ptr) != 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sem_wait(sem_t* sem) {
|
||||
uint32_t shared = SEM_GET_SHARED(sem);
|
||||
|
||||
while (true) {
|
||||
if (__sem_dec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
__futex_wait_ex(&sem->count, shared, shared|SEMCOUNT_MINUS_ONE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int sem_timedwait(sem_t* sem, const timespec* abs_timeout) {
|
||||
// POSIX says we need to try to decrement the semaphore
|
||||
// before checking the timeout value. Note that if the
|
||||
// value is currently 0, __sem_trydec() does nothing.
|
||||
if (__sem_trydec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check it as per POSIX.
|
||||
if (abs_timeout == NULL || abs_timeout->tv_sec < 0 || abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= NS_PER_S) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t shared = SEM_GET_SHARED(sem);
|
||||
|
||||
while (true) {
|
||||
// POSIX mandates CLOCK_REALTIME here.
|
||||
timespec ts;
|
||||
if (!timespec_from_absolute_timespec(ts, *abs_timeout, CLOCK_REALTIME)) {
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Try to grab the semaphore. If the value was 0, this will also change it to -1.
|
||||
if (__sem_dec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
break;
|
||||
}
|
||||
|
||||
// Contention detected. Wait for a wakeup event.
|
||||
int ret = __futex_wait_ex(&sem->count, shared, shared|SEMCOUNT_MINUS_ONE, &ts);
|
||||
|
||||
// Return in case of timeout or interrupt.
|
||||
if (ret == -ETIMEDOUT || ret == -EINTR) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_post(sem_t* sem) {
|
||||
uint32_t shared = SEM_GET_SHARED(sem);
|
||||
|
||||
ANDROID_MEMBAR_FULL();
|
||||
int old_value = __sem_inc(&sem->count);
|
||||
if (old_value < 0) {
|
||||
// Contention on the semaphore. Wake up all waiters.
|
||||
__futex_wake_ex(&sem->count, shared, INT_MAX);
|
||||
} else if (old_value == SEM_VALUE_MAX) {
|
||||
// Overflow detected.
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_trywait(sem_t* sem) {
|
||||
if (__sem_trydec(&sem->count) > 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
} else {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int sem_getvalue(sem_t* sem, int* sval) {
|
||||
int val = SEMCOUNT_TO_VALUE(sem->count);
|
||||
if (val < 0) {
|
||||
val = 0;
|
||||
}
|
||||
|
||||
*sval = val;
|
||||
return 0;
|
||||
}
|
@@ -1,11 +1,16 @@
|
||||
/* $OpenBSD: strerror_r.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
|
||||
/* Public Domain <marc@snafu.org> */
|
||||
|
||||
// G++ automatically defines _GNU_SOURCE, which then means that <string.h>
|
||||
// gives us the GNU variant.
|
||||
#undef _GNU_SOURCE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "private/ErrnoRestorer.h"
|
||||
#include "private/libc_logging.h"
|
||||
@@ -62,6 +67,12 @@ int strerror_r(int error_number, char* buf, size_t buf_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" char* __gnu_strerror_r(int error_number, char* buf, size_t buf_len) {
|
||||
ErrnoRestorer errno_restorer; // The glibc strerror_r doesn't set errno if it truncates...
|
||||
strerror_r(error_number, buf, buf_len);
|
||||
return buf; // ...and just returns whatever fit.
|
||||
}
|
||||
|
||||
extern "C" __LIBC_HIDDEN__ const char* __strsignal(int signal_number, char* buf, size_t buf_len) {
|
||||
const char* signal_name = __strsignal_lookup(signal_number);
|
||||
if (signal_name != NULL) {
|
||||
|
@@ -49,7 +49,6 @@
|
||||
#define SYSTEM_MQ_OPEN_MAX 8
|
||||
#define SYSTEM_MQ_PRIO_MAX 32768
|
||||
#define SYSTEM_SEM_NSEMS_MAX 256
|
||||
#define SYSTEM_SEM_VALUE_MAX 0x3fffffff /* see bionic/semaphore.c */
|
||||
#define SYSTEM_SIGQUEUE_MAX 32
|
||||
#define SYSTEM_TIMER_MAX 32
|
||||
#define SYSTEM_LOGIN_NAME_MAX 256
|
||||
@@ -95,7 +94,7 @@ static int __sysconf_nprocessors_conf() {
|
||||
}
|
||||
|
||||
static int __sysconf_nprocessors_onln() {
|
||||
FILE* fp = fopen("/proc/stat", "r");
|
||||
FILE* fp = fopen("/proc/stat", "re");
|
||||
if (fp == NULL) {
|
||||
return 1;
|
||||
}
|
||||
@@ -118,7 +117,7 @@ static int __sysconf_nprocessors_onln() {
|
||||
}
|
||||
|
||||
static int __get_meminfo(const char* pattern) {
|
||||
FILE* fp = fopen("/proc/meminfo", "r");
|
||||
FILE* fp = fopen("/proc/meminfo", "re");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -150,37 +149,15 @@ static int __sysconf_monotonic_clock() {
|
||||
return (rc == -1) ? -1 : _POSIX_VERSION;
|
||||
}
|
||||
|
||||
long sysconf(int name) {
|
||||
switch (name) {
|
||||
#ifdef _POSIX_ARG_MAX
|
||||
int sysconf(int name) {
|
||||
switch (name) {
|
||||
case _SC_ARG_MAX: return _POSIX_ARG_MAX;
|
||||
#endif
|
||||
#ifdef _POSIX2_BC_BASE_MAX
|
||||
case _SC_BC_BASE_MAX: return _POSIX2_BC_BASE_MAX;
|
||||
#endif
|
||||
#ifdef _POSIX2_BC_DIM_MAX
|
||||
case _SC_BC_DIM_MAX: return _POSIX2_BC_DIM_MAX;
|
||||
#endif
|
||||
#ifdef _POSIX2_BC_SCALE_MAX
|
||||
case _SC_BC_SCALE_MAX: return _POSIX2_BC_SCALE_MAX;
|
||||
#endif
|
||||
#ifdef _POSIX2_BC_STRING_MAX
|
||||
case _SC_BC_STRING_MAX: return _POSIX2_BC_STRING_MAX;
|
||||
#endif
|
||||
case _SC_CHILD_MAX: return CHILD_MAX;
|
||||
case _SC_CLK_TCK: return SYSTEM_CLK_TCK;
|
||||
#ifdef _POSIX2_COLL_WEIGHTS_MASK
|
||||
case _SC_COLL_WEIGHTS_MAX: return _POSIX2_COLL_WEIGHTS_MASK;
|
||||
#endif
|
||||
#ifdef _POSIX2_EXPR_NEST_MAX
|
||||
case _SC_EXPR_NEST_MAX: return _POSIX2_EXPR_NEST_MAX;
|
||||
#endif
|
||||
#ifdef _POSIX2_LINE_MAX
|
||||
case _SC_LINE_MAX: return _POSIX2_LINE_MAX;
|
||||
#endif
|
||||
case _SC_NGROUPS_MAX: return NGROUPS_MAX;
|
||||
case _SC_OPEN_MAX: return OPEN_MAX;
|
||||
//case _SC_PASS_MAX: return PASS_MAX;
|
||||
case _SC_PASS_MAX: return PASS_MAX;
|
||||
case _SC_2_C_BIND: return SYSTEM_2_C_BIND;
|
||||
case _SC_2_C_DEV: return SYSTEM_2_C_DEV;
|
||||
case _SC_2_C_VERSION: return SYSTEM_2_C_VER;
|
||||
@@ -191,42 +168,20 @@ long sysconf(int name) {
|
||||
case _SC_2_SW_DEV: return SYSTEM_2_SW_DEV;
|
||||
case _SC_2_UPE: return SYSTEM_2_UPE;
|
||||
case _SC_2_VERSION: return SYSTEM_2_VERSION;
|
||||
#ifdef _POSIX_JOB_CONTROL
|
||||
case _SC_JOB_CONTROL: return _POSIX_JOB_CONTROL;
|
||||
#endif
|
||||
#ifdef _POSIX_SAVED_IDS
|
||||
case _SC_SAVED_IDS: return _POSIX_SAVED_IDS;
|
||||
#endif
|
||||
#ifdef _POSIX_VERSION
|
||||
case _SC_VERSION: return _POSIX_VERSION;
|
||||
#endif
|
||||
//case _SC_RE_DUP_<AX: return ;
|
||||
case _SC_RE_DUP_MAX: return _POSIX_RE_DUP_MAX;
|
||||
case _SC_STREAM_MAX: return FOPEN_MAX;
|
||||
//case _SC_TZNAME_MAX: return ;
|
||||
#if _XOPEN_CRYPT
|
||||
case _SC_TZNAME_MAX: return _POSIX_TZNAME_MAX;
|
||||
case _SC_XOPEN_CRYPT: return _XOPEN_CRYPT;
|
||||
#endif
|
||||
#ifdef _XOPEN_ENH_I18N
|
||||
case _SC_XOPEN_ENH_I18N: return _XOPEN_ENH_I18N;
|
||||
#endif
|
||||
#ifdef _XOPEN_SHM
|
||||
case _SC_XOPEN_SHM: return _XOPEN_SHM;
|
||||
#endif
|
||||
#ifdef _XOPEN_VERSION
|
||||
//case _SC_XOPEN_SHM: return _XOPEN_SHM;
|
||||
case _SC_XOPEN_VERSION: return _XOPEN_VERSION;
|
||||
#endif
|
||||
#ifdef _XOPEN_XCU_VERSION
|
||||
case _SC_XOPEN_XCU_VERSION: return _XOPEN_XCU_VERSION;
|
||||
#endif
|
||||
#ifdef _XOPEN_REALTIME
|
||||
case _SC_XOPEN_REALTIME: return _XOPEN_REALTIME;
|
||||
#endif
|
||||
#ifdef _XOPEN_REALTIME_THREADS
|
||||
case _SC_XOPEN_REALTIME_THREADS: return _XOPEN_REALTIME_THREADS;
|
||||
#endif
|
||||
#ifdef _XOPEN_LEGACY
|
||||
case _SC_XOPEN_LEGACY: return _XOPEN_LEGACY;
|
||||
#endif
|
||||
case _SC_ATEXIT_MAX: return SYSTEM_ATEXIT_MAX;
|
||||
case _SC_IOV_MAX: return SYSTEM_IOV_MAX;
|
||||
|
||||
@@ -234,71 +189,35 @@ long sysconf(int name) {
|
||||
case _SC_PAGE_SIZE:
|
||||
return PAGE_SIZE;
|
||||
|
||||
#ifdef _XOPEN_UNIX
|
||||
case _SC_XOPEN_UNIX: return _XOPEN_UNIX;
|
||||
#endif
|
||||
|
||||
// XXX: TODO: XBS5 nonsense
|
||||
|
||||
#ifdef AIO_LISTIO_MAX
|
||||
case _SC_AIO_LISTIO_MAX: return AIO_LISTIO_MAX;
|
||||
#endif
|
||||
#ifdef AIO_MAX
|
||||
case _SC_AIO_MAX: return AIO_MAX;
|
||||
#endif
|
||||
#ifdef AIO_PRIO_DELTA_MAX
|
||||
case _SC_AIO_PRIO_DELTA_MAX: return AIO_PRIO_DELTA_MAX;
|
||||
#endif
|
||||
//case _SC_AIO_LISTIO_MAX: return AIO_LISTIO_MAX;
|
||||
//case _SC_AIO_MAX: return AIO_MAX;
|
||||
//case _SC_AIO_PRIO_DELTA_MAX: return AIO_PRIO_DELTA_MAX;
|
||||
case _SC_DELAYTIMER_MAX: return SYSTEM_DELAYTIMER_MAX;
|
||||
case _SC_MQ_OPEN_MAX: return SYSTEM_MQ_OPEN_MAX;
|
||||
case _SC_MQ_PRIO_MAX: return SYSTEM_MQ_PRIO_MAX;
|
||||
case _SC_RTSIG_MAX: return RTSIG_MAX;
|
||||
case _SC_SEM_NSEMS_MAX: return SYSTEM_SEM_NSEMS_MAX;
|
||||
case _SC_SEM_VALUE_MAX: return SYSTEM_SEM_VALUE_MAX;
|
||||
case _SC_SEM_VALUE_MAX: return SEM_VALUE_MAX;
|
||||
case _SC_SIGQUEUE_MAX: return SYSTEM_SIGQUEUE_MAX;
|
||||
case _SC_TIMER_MAX: return SYSTEM_TIMER_MAX;
|
||||
#ifdef _POSIX_ASYNCHRONOUS_IO
|
||||
case _SC_ASYNCHRONOUS_IO: return _POSIX_ASYNCHRONOUS_IO;
|
||||
#endif
|
||||
#ifdef _POSIX_FSYNC
|
||||
//case _SC_ASYNCHRONOUS_IO: return _POSIX_ASYNCHRONOUS_IO;
|
||||
case _SC_FSYNC: return _POSIX_FSYNC;
|
||||
#endif
|
||||
#ifdef _POSIX_MAPPED_FILES
|
||||
case _SC_MAPPED_FILES: return _POSIX_MAPPED_FILES;
|
||||
#endif
|
||||
#ifdef _POSIX_MEMLOCK
|
||||
case _SC_MEMLOCK: return _POSIX_MEMLOCK;
|
||||
#endif
|
||||
#ifdef _POSIX_MEMLOCK_RANGE
|
||||
case _SC_MEMLOCK_RANGE: return _POSIX_MEMLOCK_RANGE
|
||||
#endif
|
||||
#ifdef _POSIX_MEMORY_PROTECTION
|
||||
case _SC_MEMORY_PROTECTION: return _POSIX_MEMORY_PROTECTION;
|
||||
#endif
|
||||
#ifdef _POSIX_MESSAGE_PASSING
|
||||
case _SC_MESSAGE_PASSING: return _POSIX_MESSAGE_PASSING;
|
||||
#endif
|
||||
#ifdef _POSIX_PRIORITIZED_IO
|
||||
case _SC_PRIORITIZED_IO: return _POSIX_PRIORITIZED_IO;
|
||||
#endif
|
||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||
//case _SC_MEMLOCK: return _POSIX_MEMLOCK;
|
||||
//case _SC_MEMLOCK_RANGE: return _POSIX_MEMLOCK_RANGE;
|
||||
//case _SC_MEMORY_PROTECTION: return _POSIX_MEMORY_PROTECTION;
|
||||
//case _SC_MESSAGE_PASSING: return _POSIX_MESSAGE_PASSING;
|
||||
//case _SC_PRIORITIZED_IO: return _POSIX_PRIORITIZED_IO;
|
||||
case _SC_PRIORITY_SCHEDULING: return _POSIX_PRIORITY_SCHEDULING;
|
||||
#endif
|
||||
#ifdef _POSIX_REALTIME_SIGNALS
|
||||
case _SC_REALTIME_SIGNALS: return _POSIX_REALTIME_SIGNALS;
|
||||
#endif
|
||||
#ifdef _POSIX_SEMAPHORES
|
||||
case _SC_SEMAPHORES: return _POSIX_SEMAPHORES;
|
||||
#endif
|
||||
#ifdef _POSIX_SHARED_MEMORY_OBJECTS
|
||||
case _SC_SHARED_MEMORY_OBJECTS: return _POSIX_SHARED_MEMORY_OBJECTS;
|
||||
#endif
|
||||
#ifdef _POSIX_SYNCHRONIZED_IO
|
||||
//case _SC_SHARED_MEMORY_OBJECTS: return _POSIX_SHARED_MEMORY_OBJECTS;
|
||||
case _SC_SYNCHRONIZED_IO: return _POSIX_SYNCHRONIZED_IO;
|
||||
#endif
|
||||
#ifdef _POSIX_TIMERS
|
||||
case _SC_TIMERS: return _POSIX_TIMERS;
|
||||
#endif
|
||||
|
||||
case _SC_GETGR_R_SIZE_MAX: return 1024;
|
||||
case _SC_GETPW_R_SIZE_MAX: return 1024;
|
||||
@@ -314,25 +233,15 @@ long sysconf(int name) {
|
||||
case _SC_THREAD_STACK_MIN: return PTHREAD_STACK_MIN;
|
||||
case _SC_THREAD_THREADS_MAX: return SYSTEM_THREAD_THREADS_MAX;
|
||||
case _SC_TTY_NAME_MAX: return SYSTEM_TTY_NAME_MAX;
|
||||
#ifdef _POSIX_THREADS
|
||||
case _SC_THREADS: return _POSIX_THREADS;
|
||||
#endif
|
||||
|
||||
case _SC_THREAD_ATTR_STACKADDR: return -1; // Removed in POSIX 2008
|
||||
case _SC_THREAD_ATTR_STACKSIZE: return -1; // Removed in POSIX 2008
|
||||
|
||||
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
|
||||
case _SC_THREAD_PRIORITY_SCHEDULING: return _POSIX_THREAD_PRIORITY_SCHEDULING;
|
||||
#endif
|
||||
#ifdef _POSIX_THREAD_PRIO_INHERIT
|
||||
//case _SC_THREAD_PRIORITY_SCHEDULING: return _POSIX_THREAD_PRIORITY_SCHEDULING;
|
||||
case _SC_THREAD_PRIO_INHERIT: return _POSIX_THREAD_PRIO_INHERIT;
|
||||
#endif
|
||||
#ifdef _POSIX_THREAD_PRIO_PROTECT
|
||||
case _SC_THREAD_PRIO_PROTECT: return _POSIX_THREAD_PRIO_PROTECT;
|
||||
#endif
|
||||
#ifdef _POSIX_THREAD_SAFE_FUNCTIONS
|
||||
case _SC_THREAD_SAFE_FUNCTIONS: return _POSIX_THREAD_SAFE_FUNCTIONS
|
||||
#endif
|
||||
//case _SC_THREAD_SAFE_FUNCTIONS: return _POSIX_THREAD_SAFE_FUNCTIONS
|
||||
|
||||
case _SC_MONOTONIC_CLOCK: return __sysconf_monotonic_clock();
|
||||
case _SC_NPROCESSORS_CONF: return __sysconf_nprocessors_conf();
|
||||
@@ -341,9 +250,9 @@ long sysconf(int name) {
|
||||
case _SC_AVPHYS_PAGES: return __sysconf_avphys_pages();
|
||||
|
||||
default:
|
||||
/* Posix says EINVAL is the only error that shall be returned,
|
||||
* but GLibc uses ENOSYS */
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
// Posix says EINVAL is the only error that shall be returned,
|
||||
// but glibc uses ENOSYS.
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <new>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -45,7 +46,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
@@ -80,6 +80,16 @@ struct prop_bt {
|
||||
uint8_t namelen;
|
||||
uint8_t reserved[3];
|
||||
|
||||
// TODO: The following fields should be declared as atomic_uint32_t.
|
||||
// They should be assigned to with release semantics, instead of using
|
||||
// explicit fences. Unfortunately, the read accesses are generally
|
||||
// followed by more dependent read accesses, and the dependence
|
||||
// is assumed to enforce memory ordering. Which it does on supported
|
||||
// hardware. This technically should use memory_order_consume, if
|
||||
// that worked as intended.
|
||||
// We should also avoid rereading these fields redundantly, since not
|
||||
// all processor implementations ensure that multiple loads from the
|
||||
// same field are carried out in the right order.
|
||||
volatile uint32_t prop;
|
||||
|
||||
volatile uint32_t left;
|
||||
@@ -93,7 +103,8 @@ struct prop_bt {
|
||||
this->namelen = name_length;
|
||||
memcpy(this->name, name, name_length);
|
||||
this->name[name_length] = '\0';
|
||||
ANDROID_MEMBAR_FULL();
|
||||
ANDROID_MEMBAR_FULL(); // TODO: Instead use a release store
|
||||
// for subsequent pointer assignment.
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -102,14 +113,15 @@ private:
|
||||
|
||||
struct prop_area {
|
||||
uint32_t bytes_used;
|
||||
volatile uint32_t serial;
|
||||
atomic_uint_least32_t serial;
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t reserved[28];
|
||||
char data[0];
|
||||
|
||||
prop_area(const uint32_t magic, const uint32_t version) :
|
||||
serial(0), magic(magic), version(version) {
|
||||
magic(magic), version(version) {
|
||||
atomic_init(&serial, 0);
|
||||
memset(reserved, 0, sizeof(reserved));
|
||||
// Allocate enough space for the root node.
|
||||
bytes_used = sizeof(prop_bt);
|
||||
@@ -120,7 +132,7 @@ private:
|
||||
};
|
||||
|
||||
struct prop_info {
|
||||
volatile uint32_t serial;
|
||||
atomic_uint_least32_t serial;
|
||||
char value[PROP_VALUE_MAX];
|
||||
char name[0];
|
||||
|
||||
@@ -128,10 +140,11 @@ struct prop_info {
|
||||
const uint8_t valuelen) {
|
||||
memcpy(this->name, name, namelen);
|
||||
this->name[namelen] = '\0';
|
||||
this->serial = (valuelen << 24);
|
||||
atomic_init(&this->serial, valuelen << 24);
|
||||
memcpy(this->value, value, valuelen);
|
||||
this->value[valuelen] = '\0';
|
||||
ANDROID_MEMBAR_FULL();
|
||||
ANDROID_MEMBAR_FULL(); // TODO: Instead use a release store
|
||||
// for subsequent point assignment.
|
||||
}
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(prop_info);
|
||||
@@ -188,14 +201,6 @@ static int map_prop_area_rw()
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: Is this really required ? Does android run on any kernels that
|
||||
// don't support O_CLOEXEC ?
|
||||
const int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, PA_SIZE) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
@@ -258,18 +263,9 @@ static int map_fd_ro(const int fd) {
|
||||
|
||||
static int map_prop_area()
|
||||
{
|
||||
int fd(open(property_filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
|
||||
if (fd >= 0) {
|
||||
/* For old kernels that don't support O_CLOEXEC */
|
||||
const int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int fd = open(property_filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
|
||||
bool close_fd = true;
|
||||
if ((fd < 0) && (errno == ENOENT)) {
|
||||
if (fd == -1 && errno == ENOENT) {
|
||||
/*
|
||||
* For backwards compatibility, if the file doesn't
|
||||
* exist, we use the environment to get the file descriptor.
|
||||
@@ -598,6 +594,14 @@ const prop_info *__system_property_find(const char *name)
|
||||
return find_property(root_node(), name, strlen(name), NULL, 0, false);
|
||||
}
|
||||
|
||||
// The C11 standard doesn't allow atomic loads from const fields,
|
||||
// though C++11 does. Fudge it until standards get straightened out.
|
||||
static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s,
|
||||
memory_order mo) {
|
||||
atomic_uint_least32_t* non_const_s = const_cast<atomic_uint_least32_t*>(s);
|
||||
return atomic_load_explicit(non_const_s, mo);
|
||||
}
|
||||
|
||||
int __system_property_read(const prop_info *pi, char *name, char *value)
|
||||
{
|
||||
if (__predict_false(compat_mode)) {
|
||||
@@ -605,11 +609,20 @@ int __system_property_read(const prop_info *pi, char *name, char *value)
|
||||
}
|
||||
|
||||
while (true) {
|
||||
uint32_t serial = __system_property_serial(pi);
|
||||
uint32_t serial = __system_property_serial(pi); // acquire semantics
|
||||
size_t len = SERIAL_VALUE_LEN(serial);
|
||||
memcpy(value, pi->value, len + 1);
|
||||
ANDROID_MEMBAR_FULL();
|
||||
if (serial == pi->serial) {
|
||||
// TODO: Fix the synchronization scheme here.
|
||||
// There is no fully supported way to implement this kind
|
||||
// of synchronization in C++11, since the memcpy races with
|
||||
// updates to pi, and the data being accessed is not atomic.
|
||||
// The following fence is unintuitive, but would be the
|
||||
// correct one if memcpy used memory_order_relaxed atomic accesses.
|
||||
// In practice it seems unlikely that the generated code would
|
||||
// would be any different, so this should be OK.
|
||||
atomic_thread_fence(memory_order_acquire);
|
||||
if (serial ==
|
||||
load_const_atomic(&(pi->serial), memory_order_relaxed)) {
|
||||
if (name != 0) {
|
||||
strcpy(name, pi->name);
|
||||
}
|
||||
@@ -658,14 +671,24 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len)
|
||||
if (len >= PROP_VALUE_MAX)
|
||||
return -1;
|
||||
|
||||
pi->serial = pi->serial | 1;
|
||||
ANDROID_MEMBAR_FULL();
|
||||
uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
|
||||
serial |= 1;
|
||||
atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);
|
||||
// The memcpy call here also races. Again pretend it
|
||||
// used memory_order_relaxed atomics, and use the analogous
|
||||
// counterintuitive fence.
|
||||
atomic_thread_fence(memory_order_release);
|
||||
memcpy(pi->value, value, len + 1);
|
||||
ANDROID_MEMBAR_FULL();
|
||||
pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff);
|
||||
atomic_store_explicit(
|
||||
&pi->serial,
|
||||
(len << 24) | ((serial + 1) & 0xffffff),
|
||||
memory_order_release);
|
||||
__futex_wake(&pi->serial, INT32_MAX);
|
||||
|
||||
pa->serial++;
|
||||
atomic_store_explicit(
|
||||
&pa->serial,
|
||||
atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
|
||||
memory_order_release);
|
||||
__futex_wake(&pa->serial, INT32_MAX);
|
||||
|
||||
return 0;
|
||||
@@ -688,17 +711,25 @@ int __system_property_add(const char *name, unsigned int namelen,
|
||||
if (!pi)
|
||||
return -1;
|
||||
|
||||
pa->serial++;
|
||||
// There is only a single mutator, but we want to make sure that
|
||||
// updates are visible to a reader waiting for the update.
|
||||
atomic_store_explicit(
|
||||
&pa->serial,
|
||||
atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
|
||||
memory_order_release);
|
||||
__futex_wake(&pa->serial, INT32_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Wait for non-locked serial, and retrieve it with acquire semantics.
|
||||
unsigned int __system_property_serial(const prop_info *pi)
|
||||
{
|
||||
uint32_t serial = pi->serial;
|
||||
uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
|
||||
while (SERIAL_DIRTY(serial)) {
|
||||
__futex_wait(const_cast<volatile uint32_t*>(&pi->serial), serial, NULL);
|
||||
serial = pi->serial;
|
||||
__futex_wait(const_cast<volatile void *>(
|
||||
reinterpret_cast<const void *>(&pi->serial)),
|
||||
serial, NULL);
|
||||
serial = load_const_atomic(&pi->serial, memory_order_acquire);
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
@@ -706,12 +737,14 @@ unsigned int __system_property_serial(const prop_info *pi)
|
||||
unsigned int __system_property_wait_any(unsigned int serial)
|
||||
{
|
||||
prop_area *pa = __system_property_area__;
|
||||
uint32_t my_serial;
|
||||
|
||||
do {
|
||||
__futex_wait(&pa->serial, serial, NULL);
|
||||
} while (pa->serial == serial);
|
||||
my_serial = atomic_load_explicit(&pa->serial, memory_order_acquire);
|
||||
} while (my_serial == serial);
|
||||
|
||||
return pa->serial;
|
||||
return my_serial;
|
||||
}
|
||||
|
||||
const prop_info *__system_property_find_nth(unsigned n)
|
||||
|
@@ -748,10 +748,24 @@ static int valid_tm_mon( const struct TM* date ) {
|
||||
char *asctime64_r( const struct TM* date, char *result ) {
|
||||
/* I figure everything else can be displayed, even hour 25, but if
|
||||
these are out of range we walk off the name arrays */
|
||||
if( !valid_tm_wday(date) || !valid_tm_mon(date) )
|
||||
if (!valid_tm_wday(date) || !valid_tm_mon(date)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
|
||||
/* Docs state this function does not support years beyond 9999. */
|
||||
if (1900 + date->tm_year > 9999) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The IBM docs for this function state that the result buffer can be
|
||||
* assumed to be at least 26 bytes wide. The docs also state that this is
|
||||
* only valid for years <= 9999, so we know this format string will not
|
||||
* print more than that many characters.
|
||||
*
|
||||
* http://www-01.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/asctimer.htm
|
||||
*/
|
||||
snprintf(result, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
|
||||
wday_name[date->tm_wday],
|
||||
mon_name[date->tm_mon],
|
||||
date->tm_mday, date->tm_hour,
|
||||
|
@@ -565,7 +565,7 @@ android_read_hostent(FILE* proxy)
|
||||
char buf[4];
|
||||
if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) return NULL;
|
||||
|
||||
/* This is reading serialized data from system/netd/server/DnsProxyListener.cpp
|
||||
/* This is reading serialized data from system/netd/DnsProxyListener.cpp
|
||||
* and changes here need to be matched there */
|
||||
int result_code = strtol(buf, NULL, 10);
|
||||
if (result_code != DnsProxyQueryResult) {
|
||||
@@ -763,7 +763,7 @@ gethostbyname_internal(const char *name, int af, res_state res, unsigned netid,
|
||||
|
||||
netid = __netdClientDispatch.netIdForResolv(netid);
|
||||
|
||||
/* This is writing to system/netd/server/DnsProxyListener.cpp and changes
|
||||
/* This is writing to system/netd/DnsProxyListener.cpp and changes
|
||||
* here need to be matched there */
|
||||
if (fprintf(proxy, "gethostbyname %u %s %d",
|
||||
netid,
|
||||
@@ -899,7 +899,7 @@ _sethtent(int f)
|
||||
res_static rs = __res_get_static();
|
||||
if (rs == NULL) return;
|
||||
if (!rs->hostf)
|
||||
rs->hostf = fopen(_PATH_HOSTS, "r" );
|
||||
rs->hostf = fopen(_PATH_HOSTS, "re" );
|
||||
else
|
||||
rewind(rs->hostf);
|
||||
rs->stayopen = f;
|
||||
@@ -925,7 +925,7 @@ _gethtent(void)
|
||||
int af, len;
|
||||
res_static rs = __res_get_static();
|
||||
|
||||
if (!rs->hostf && !(rs->hostf = fopen(_PATH_HOSTS, "r" ))) {
|
||||
if (!rs->hostf && !(rs->hostf = fopen(_PATH_HOSTS, "re" ))) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -32,6 +32,11 @@
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
struct __res_state;
|
||||
struct resolv_cache; /* forward */
|
||||
|
||||
/* Gets the cache for a network. Returned cache might be NULL. */
|
||||
__LIBC_HIDDEN__
|
||||
extern struct resolv_cache* __get_res_cache(unsigned netid);
|
||||
|
||||
/* sets the name server addresses to the provided res_state structure. The
|
||||
* name servers are retrieved from the cache which is associated
|
||||
@@ -48,7 +53,7 @@ typedef enum {
|
||||
|
||||
__LIBC_HIDDEN__
|
||||
extern ResolvCacheStatus
|
||||
_resolv_cache_lookup( unsigned netid,
|
||||
_resolv_cache_lookup( struct resolv_cache* cache,
|
||||
const void* query,
|
||||
int querylen,
|
||||
void* answer,
|
||||
@@ -60,7 +65,7 @@ _resolv_cache_lookup( unsigned netid,
|
||||
*/
|
||||
__LIBC_HIDDEN__
|
||||
extern void
|
||||
_resolv_cache_add( unsigned netid,
|
||||
_resolv_cache_add( struct resolv_cache* cache,
|
||||
const void* query,
|
||||
int querylen,
|
||||
const void* answer,
|
||||
@@ -69,7 +74,7 @@ _resolv_cache_add( unsigned netid,
|
||||
/* Notify the cache a request failed */
|
||||
__LIBC_HIDDEN__
|
||||
extern void
|
||||
_resolv_cache_query_failed( unsigned netid,
|
||||
_resolv_cache_query_failed( struct resolv_cache* cache,
|
||||
const void* query,
|
||||
int querylen);
|
||||
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include <netinet/in.h>
|
||||
|
||||
/*
|
||||
* Passing NETID_UNSET as the netId causes system/netd/server/DnsProxyListener.cpp to
|
||||
* Passing NETID_UNSET as the netId causes system/netd/DnsProxyListener.cpp to
|
||||
* fill in the appropriate default netId for the query.
|
||||
*/
|
||||
#define NETID_UNSET 0u
|
||||
@@ -72,9 +72,6 @@ struct hostent *android_gethostbyaddrfornet_proxy(const void *, socklen_t, int ,
|
||||
int android_getnameinfofornet(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t,
|
||||
int, unsigned, unsigned);
|
||||
|
||||
/* delete the cache associated with a certain network */
|
||||
extern void _resolv_delete_cache_for_net(unsigned netid);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RESOLV_NETID_H */
|
||||
|
@@ -426,7 +426,7 @@ int b64_ntop(u_char const *, size_t, char *, size_t);
|
||||
int b64_pton(char const *, u_char *, size_t);
|
||||
#endif
|
||||
int loc_aton(const char *, u_char *);
|
||||
const char * loc_ntoa(const u_char *, char *);
|
||||
const char * loc_ntoa(const u_char *, char *, size_t);
|
||||
int dn_skipname(const u_char *, const u_char *);
|
||||
void putlong(uint32_t, u_char *);
|
||||
void putshort(uint16_t, u_char *);
|
||||
@@ -498,16 +498,6 @@ __LIBC_HIDDEN__ void res_setnetid(res_state, unsigned);
|
||||
__LIBC_HIDDEN__ void res_setmark(res_state, unsigned);
|
||||
u_int res_randomid(void);
|
||||
|
||||
#ifdef __i386__
|
||||
# define __socketcall extern __attribute__((__cdecl__))
|
||||
#else
|
||||
# define __socketcall extern
|
||||
#endif
|
||||
|
||||
__socketcall int __connect(int, const struct sockaddr*, socklen_t);
|
||||
|
||||
#undef __socketcall
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#pragma GCC visibility pop
|
||||
|
@@ -43,12 +43,6 @@ __RCSID("$NetBSD: ns_name.c,v 1.9 2012/03/13 21:13:39 christos Exp $");
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) ((int)strlen(sprintf/**/x))
|
||||
#else
|
||||
# define SPRINTF(x) (sprintf x)
|
||||
#endif
|
||||
|
||||
#define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
|
||||
#define DNS_LABELTYPE_BITSTRING 0x41
|
||||
|
||||
@@ -1012,31 +1006,31 @@ decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
|
||||
return(-1);
|
||||
|
||||
cp++;
|
||||
i = SPRINTF((dn, "\\[x"));
|
||||
i = snprintf(dn, eom - dn, "\\[x");
|
||||
if (i < 0)
|
||||
return (-1);
|
||||
dn += i;
|
||||
for (b = blen; b > 7; b -= 8, cp++) {
|
||||
i = SPRINTF((dn, "%02x", *cp & 0xff));
|
||||
i = snprintf(dn, eom - dn, "%02x", *cp & 0xff);
|
||||
if (i < 0)
|
||||
return (-1);
|
||||
dn += i;
|
||||
}
|
||||
if (b > 4) {
|
||||
tc = *cp++;
|
||||
i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
|
||||
i = snprintf(dn, eom - dn, "%02x", tc & (0xff << (8 - b)));
|
||||
if (i < 0)
|
||||
return (-1);
|
||||
dn += i;
|
||||
} else if (b > 0) {
|
||||
tc = *cp++;
|
||||
i = SPRINTF((dn, "%1x",
|
||||
(((u_int32_t)tc >> 4) & 0x0f) & (0x0f << (4 - b))));
|
||||
i = snprintf(dn, eom - dn, "%1x",
|
||||
(((u_int32_t)tc >> 4) & 0x0f) & (0x0f << (4 - b)));
|
||||
if (i < 0)
|
||||
return (-1);
|
||||
dn += i;
|
||||
}
|
||||
i = SPRINTF((dn, "/%d]", blen));
|
||||
i = snprintf(dn, eom - dn, "/%d]", blen);
|
||||
if (i < 0)
|
||||
return (-1);
|
||||
dn += i;
|
||||
|
@@ -48,12 +48,6 @@ __RCSID("$NetBSD: ns_print.c,v 1.11 2012/03/13 21:13:39 christos Exp $");
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) ((int)strlen(sprintf/**/x))
|
||||
#else
|
||||
# define SPRINTF(x) (sprintf x)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
@@ -155,7 +149,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
*/
|
||||
T(x = ns_format_ttl(ttl, buf, buflen));
|
||||
addlen((size_t)x, &buf, &buflen);
|
||||
len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
|
||||
len = snprintf(tmp, sizeof(tmp), " %s %s", p_class(class), p_type(type));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
T(spaced = addtab((size_t)(x + len), (size_t)16, spaced, &buf, &buflen));
|
||||
|
||||
@@ -218,7 +212,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
/* Serial number. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
|
||||
len = SPRINTF((tmp, "%lu", t));
|
||||
len = snprintf(tmp, sizeof(tmp), "%lu", t);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
|
||||
T(addstr("; serial\n", (size_t)9, &buf, &buflen));
|
||||
@@ -275,7 +269,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
/* Priority. */
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", t);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Target. */
|
||||
@@ -293,7 +287,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
/* Priority. */
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", t);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Name1. */
|
||||
@@ -344,7 +338,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
char t[255];
|
||||
|
||||
/* XXX protocol format checking? */
|
||||
(void) loc_ntoa(rdata, t);
|
||||
(void) loc_ntoa(rdata, t, sizeof(t));
|
||||
T(addstr(t, strlen(t), &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
@@ -359,7 +353,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
/* Order, Precedence. */
|
||||
order = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
preference = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((t, "%u %u ", order, preference));
|
||||
len = snprintf(t, sizeof(t), "%u %u ", order, preference);
|
||||
T(addstr(t, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Flags. */
|
||||
@@ -401,7 +395,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
priority = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
weight = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
port = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((t, "%u %u %u ", priority, weight, port));
|
||||
len = snprintf(t, sizeof(t), "%u %u %u ", priority, weight, port);
|
||||
T(addstr(t, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Server. */
|
||||
@@ -432,7 +426,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
rdata += NS_INADDRSZ;
|
||||
|
||||
/* Protocol. */
|
||||
len = SPRINTF((tmp, " %u ( ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), " %u ( ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata += NS_INT8SZ;
|
||||
|
||||
@@ -449,7 +443,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
lcnt = 10;
|
||||
spaced = 0;
|
||||
}
|
||||
len = SPRINTF((tmp, "%d ", n));
|
||||
len = snprintf(tmp, sizeof(tmp), "%d ", n);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
lcnt--;
|
||||
}
|
||||
@@ -480,8 +474,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
protocol = *rdata++;
|
||||
algorithm = *rdata++;
|
||||
len = SPRINTF((tmp, "0x%04x %u %u",
|
||||
keyflags, protocol, algorithm));
|
||||
len = snprintf(tmp, sizeof(tmp), "0x%04x %u %u",
|
||||
keyflags, protocol, algorithm);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Public key data. */
|
||||
@@ -502,7 +496,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
}
|
||||
if (len > 15)
|
||||
T(addstr(" )", (size_t)2, &buf, &buflen));
|
||||
n = SPRINTF((tmp, " ; key_tag= %u", key_id));
|
||||
n = snprintf(tmp, sizeof(tmp), " ; key_tag= %u", key_id);
|
||||
T(addstr(tmp, (size_t)n, &buf, &buflen));
|
||||
|
||||
break;
|
||||
@@ -524,25 +518,25 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
algorithm = *rdata++;
|
||||
labels = *rdata++;
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s %d %d %lu ",
|
||||
p_type((int)typ), algorithm, labels, t));
|
||||
len = snprintf(tmp, sizeof(tmp), "%s %d %d %lu ",
|
||||
p_type((int)typ), algorithm, labels, t);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
if (labels > (u_int)dn_count_labels(name))
|
||||
goto formerr;
|
||||
|
||||
/* Signature expiry. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Time signed. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Signature Footprint. */
|
||||
footprint = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", footprint));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", footprint);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Signer's name. */
|
||||
@@ -579,7 +573,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
n = edata - rdata;
|
||||
for (c = 0; c < n*8; c++)
|
||||
if (NS_NXT_BIT_ISSET(c, rdata)) {
|
||||
len = SPRINTF((tmp, " %s", p_type((int)c)));
|
||||
len = snprintf(tmp, sizeof(tmp), " %s", p_type((int)c));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
}
|
||||
break;
|
||||
@@ -596,7 +590,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
alg = (u_int) *rdata++;
|
||||
|
||||
len = SPRINTF((tmp1, "%d %d %d ", c_type, key_tag, alg));
|
||||
len = snprintf(tmp1, sizeof(tmp1), "%d %d %d ", c_type, key_tag, alg);
|
||||
T(addstr(tmp1, (size_t)len, &buf, &buflen));
|
||||
siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
|
||||
if (siz > sizeof(base64_cert) * 3/4) {
|
||||
@@ -640,12 +634,12 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
|
||||
/* Inception. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Experation. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* Mode , Error, Key Size. */
|
||||
@@ -653,7 +647,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
mode = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
err = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
keysize = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u %u %u ", mode, err, keysize);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
/* XXX need to dump key, print otherdata length & other data */
|
||||
@@ -670,7 +664,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
n = ns_get16(rdata); rdata += INT16SZ;
|
||||
rdata += n; /* sig */
|
||||
n = ns_get16(rdata); rdata += INT16SZ; /* original id */
|
||||
sprintf(buf, "%d", ns_get16(rdata));
|
||||
snprintf(buf, buflen, "%d", ns_get16(rdata));
|
||||
rdata += INT16SZ;
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
break;
|
||||
@@ -682,7 +676,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
|
||||
/* prefix length */
|
||||
if (rdlen == 0U) goto formerr;
|
||||
len = SPRINTF((tmp, "%d ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%d ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
pbit = *rdata;
|
||||
if (pbit > 128) goto formerr;
|
||||
@@ -710,7 +704,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
}
|
||||
|
||||
case ns_t_opt: {
|
||||
len = SPRINTF((tmp, "%u bytes", class));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u bytes", class);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
@@ -724,21 +718,21 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
if (rdlen < 4U) goto formerr;
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", t);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
} else
|
||||
if (rdlen < 2U) goto formerr;
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
while (rdata < edata) {
|
||||
len = SPRINTF((tmp, "%02X", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%02X", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
}
|
||||
@@ -749,17 +743,17 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
case ns_t_nsec3param: {
|
||||
u_int t, w, l, j, k, c;
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", t);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
t = *rdata++;
|
||||
@@ -767,7 +761,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
T(addstr("-", 1, &buf, &buflen));
|
||||
} else {
|
||||
while (t-- > 0) {
|
||||
len = SPRINTF((tmp, "%02X", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%02X", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
}
|
||||
@@ -851,7 +845,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
if ((rdata[j] & (0x80 >> k)) == 0)
|
||||
continue;
|
||||
c = w * 256 + j * 8 + k;
|
||||
len = SPRINTF((tmp, " %s", p_type((ns_type)c)));
|
||||
len = snprintf(tmp, sizeof(tmp), " %s", p_type((ns_type)c));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
}
|
||||
}
|
||||
@@ -875,7 +869,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
if ((rdata[j] & (0x80 >> k)) == 0)
|
||||
continue;
|
||||
c = w * 256 + j * 8 + k;
|
||||
len = SPRINTF((tmp, " %s", p_type((ns_type)c)));
|
||||
len = snprintf(tmp, sizeof(tmp), " %s", p_type((ns_type)c));
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
}
|
||||
}
|
||||
@@ -949,15 +943,15 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
goto hexify;
|
||||
}
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
len = SPRINTF((tmp, "%u ", *rdata));
|
||||
len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
|
||||
@@ -1030,11 +1024,11 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
const char *str = "record too long to print";
|
||||
T(addstr(str, strlen(str), &buf, &buflen));
|
||||
} else {
|
||||
len = sprintf(tmp, "( %u ", algorithm);
|
||||
len = snprintf(tmp, sizeof(tmp), "( %u ", algorithm);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
|
||||
for (i = 0; i < hip_len; i++) {
|
||||
len = sprintf(tmp, "%02X", *rdata);
|
||||
len = snprintf(tmp, sizeof(tmp), "%02X", *rdata);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
rdata++;
|
||||
}
|
||||
@@ -1069,23 +1063,23 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
int n, m;
|
||||
char *p;
|
||||
|
||||
len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata),
|
||||
rdlen != 0U ? " (" : "", comment));
|
||||
len = snprintf(tmp, sizeof(tmp), "\\# %u%s\t; %s", (unsigned)(edata - rdata),
|
||||
rdlen != 0U ? " (" : "", comment);
|
||||
T(addstr(tmp, (size_t)len, &buf, &buflen));
|
||||
while (rdata < edata) {
|
||||
p = tmp;
|
||||
p += SPRINTF((p, "\n\t"));
|
||||
p += snprintf(p, sizeof(tmp), "\n\t");
|
||||
spaced = 0;
|
||||
n = MIN(16, (int)(edata - rdata));
|
||||
for (m = 0; m < n; m++)
|
||||
p += SPRINTF((p, "%02x ", rdata[m]));
|
||||
p += snprintf(p, sizeof(tmp) - (p - tmp), "%02x ", rdata[m]);
|
||||
T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
|
||||
if (n < 16) {
|
||||
T(addstr(")", (size_t)1, &buf, &buflen));
|
||||
T(addtab((size_t)(p - tmp + 1), (size_t)48, spaced, &buf, &buflen));
|
||||
}
|
||||
p = tmp;
|
||||
p += SPRINTF((p, "; "));
|
||||
p += snprintf(p, sizeof(tmp), "; ");
|
||||
for (m = 0; m < n; m++)
|
||||
*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
|
||||
? rdata[m]
|
||||
|
@@ -36,12 +36,6 @@ __RCSID("$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $");
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static int fmt1(int t, char s, char **buf, size_t *buflen);
|
||||
@@ -157,8 +151,8 @@ fmt1(int t, char s, char **buf, size_t *buflen) {
|
||||
char tmp[50];
|
||||
size_t len;
|
||||
|
||||
len = SPRINTF((tmp, "%d%c", t, s));
|
||||
if (len + 1 > *buflen)
|
||||
len = (size_t)snprintf(tmp, sizeof(tmp), "%d%c", t, s);
|
||||
if ((int)len < 0 || len + 1 > *buflen)
|
||||
return (-1);
|
||||
strcpy(*buf, tmp);
|
||||
*buf += len;
|
||||
|
@@ -369,7 +369,7 @@ _test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
|
||||
return 0;
|
||||
int ret;
|
||||
do {
|
||||
ret = __connect(s, addr, addrlen);
|
||||
ret = connect(s, addr, addrlen);
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
int success = (ret == 0);
|
||||
do {
|
||||
@@ -1803,7 +1803,7 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
|
||||
if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
|
||||
return 0;
|
||||
do {
|
||||
ret = __connect(sock, addr, len);
|
||||
ret = connect(sock, addr, len);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret == -1) {
|
||||
@@ -2017,7 +2017,7 @@ _sethtent(FILE **hostf)
|
||||
{
|
||||
|
||||
if (!*hostf)
|
||||
*hostf = fopen(_PATH_HOSTS, "r" );
|
||||
*hostf = fopen(_PATH_HOSTS, "re");
|
||||
else
|
||||
rewind(*hostf);
|
||||
}
|
||||
@@ -2046,7 +2046,7 @@ _gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
|
||||
assert(name != NULL);
|
||||
assert(pai != NULL);
|
||||
|
||||
if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r" )))
|
||||
if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "re")))
|
||||
return (NULL);
|
||||
again:
|
||||
if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
|
||||
|
@@ -30,8 +30,8 @@ static const char _services[] = "\
|
||||
\6tacacs\0\61u\0\
|
||||
\12re-mail-ck\0\62t\0\
|
||||
\12re-mail-ck\0\62u\0\
|
||||
\6domain\0\65t\1\12nameserver\
|
||||
\6domain\0\65u\1\12nameserver\
|
||||
\6domain\0\65t\0\
|
||||
\6domain\0\65u\0\
|
||||
\3mtp\0\71t\0\
|
||||
\11tacacs-ds\0\101t\0\
|
||||
\11tacacs-ds\0\101u\0\
|
||||
@@ -44,8 +44,8 @@ static const char _services[] = "\
|
||||
\6gopher\0\106u\0\
|
||||
\3rje\0\115t\1\6netrjs\
|
||||
\6finger\0\117t\0\
|
||||
\3www\0\120t\1\4http\
|
||||
\3www\0\120u\0\
|
||||
\4http\0\120t\1\3www\
|
||||
\4http\0\120u\0\
|
||||
\4link\0\127t\1\7ttylink\
|
||||
\10kerberos\0\130t\3\11kerberos5\4krb5\14kerberos-sec\
|
||||
\10kerberos\0\130u\3\11kerberos5\4krb5\14kerberos-sec\
|
||||
@@ -138,12 +138,16 @@ static const char _services[] = "\
|
||||
\4ldap\1\205u\0\
|
||||
\4imsp\1\226t\0\
|
||||
\4imsp\1\226u\0\
|
||||
\6svrloc\1\253t\0\
|
||||
\6svrloc\1\253u\0\
|
||||
\5https\1\273t\0\
|
||||
\5https\1\273u\0\
|
||||
\4snpp\1\274t\0\
|
||||
\4snpp\1\274u\0\
|
||||
\14microsoft-ds\1\275t\0\
|
||||
\14microsoft-ds\1\275u\0\
|
||||
\7kpasswd\1\320t\0\
|
||||
\7kpasswd\1\320u\0\
|
||||
\4saft\1\347t\0\
|
||||
\4saft\1\347u\0\
|
||||
\6isakmp\1\364t\0\
|
||||
@@ -158,6 +162,8 @@ static const char _services[] = "\
|
||||
\10npmp-gui\2\143u\1\14dqs313_execd\
|
||||
\10hmmp-ind\2\144t\1\20dqs313_intercell\
|
||||
\10hmmp-ind\2\144u\1\20dqs313_intercell\
|
||||
\4qmqp\2\164t\0\
|
||||
\4qmqp\2\164u\0\
|
||||
\3ipp\2\167t\0\
|
||||
\3ipp\2\167u\0\
|
||||
\4exec\2\0t\0\
|
||||
@@ -181,8 +187,14 @@ static const char _services[] = "\
|
||||
\4uucp\2\34t\1\5uucpd\
|
||||
\6klogin\2\37t\0\
|
||||
\6kshell\2\40t\1\5krcmd\
|
||||
\15dhcpv6-client\2\42t\0\
|
||||
\15dhcpv6-client\2\42u\0\
|
||||
\15dhcpv6-server\2\43t\0\
|
||||
\15dhcpv6-server\2\43u\0\
|
||||
\12afpovertcp\2\44t\0\
|
||||
\12afpovertcp\2\44u\0\
|
||||
\4idfp\2\45t\0\
|
||||
\4idfp\2\45u\0\
|
||||
\10remotefs\2\54t\2\12rfs_server\3rfs\
|
||||
\5nntps\2\63t\1\5snntp\
|
||||
\5nntps\2\63u\1\5snntp\
|
||||
@@ -239,19 +251,33 @@ static const char _services[] = "\
|
||||
\13sa-msg-port\6\156u\1\13old-radacct\
|
||||
\6kermit\6\161t\0\
|
||||
\6kermit\6\161u\0\
|
||||
\11groupwise\6\215t\0\
|
||||
\11groupwise\6\215u\0\
|
||||
\3l2f\6\245t\1\4l2tp\
|
||||
\3l2f\6\245u\1\4l2tp\
|
||||
\6radius\7\24t\0\
|
||||
\6radius\7\24u\0\
|
||||
\13radius-acct\7\25t\1\7radacct\
|
||||
\13radius-acct\7\25u\1\7radacct\
|
||||
\4msnp\7\107t\0\
|
||||
\4msnp\7\107u\0\
|
||||
\13unix-status\7\245t\0\
|
||||
\12log-server\7\246t\0\
|
||||
\12remoteping\7\247t\0\
|
||||
\12cisco-sccp\7\320t\0\
|
||||
\12cisco-sccp\7\320u\0\
|
||||
\6search\7\332t\1\4ndtp\
|
||||
\13pipe-server\7\332t\1\13pipe_server\
|
||||
\3nfs\10\1t\0\
|
||||
\3nfs\10\1u\0\
|
||||
\6gnunet\10\46t\0\
|
||||
\6gnunet\10\46u\0\
|
||||
\12rtcm-sc104\10\65t\0\
|
||||
\12rtcm-sc104\10\65u\0\
|
||||
\15gsigatekeeper\10\107t\0\
|
||||
\15gsigatekeeper\10\107u\0\
|
||||
\4gris\10\127t\0\
|
||||
\4gris\10\127u\0\
|
||||
\12cvspserver\11\141t\0\
|
||||
\12cvspserver\11\141u\0\
|
||||
\5venus\11\176t\0\
|
||||
@@ -266,10 +292,14 @@ static const char _services[] = "\
|
||||
\3mon\12\27u\0\
|
||||
\4dict\12\104t\0\
|
||||
\4dict\12\104u\0\
|
||||
\15f5-globalsite\12\350t\0\
|
||||
\15f5-globalsite\12\350u\0\
|
||||
\6gsiftp\12\373t\0\
|
||||
\6gsiftp\12\373u\0\
|
||||
\4gpsd\13\203t\0\
|
||||
\4gpsd\13\203u\0\
|
||||
\6gds_db\13\352t\0\
|
||||
\6gds_db\13\352u\0\
|
||||
\6gds-db\13\352t\1\6gds_db\
|
||||
\6gds-db\13\352u\1\6gds_db\
|
||||
\5icpv2\14\72t\1\3icp\
|
||||
\5icpv2\14\72u\1\3icp\
|
||||
\5mysql\14\352t\0\
|
||||
@@ -282,24 +312,49 @@ static const char _services[] = "\
|
||||
\4daap\16\151u\0\
|
||||
\3svn\16\152t\1\12subversion\
|
||||
\3svn\16\152u\1\12subversion\
|
||||
\5suucp\17\277t\0\
|
||||
\5suucp\17\277u\0\
|
||||
\6sysrqd\17\376t\0\
|
||||
\6sysrqd\17\376u\0\
|
||||
\5sieve\20\136t\0\
|
||||
\4epmd\21\21t\0\
|
||||
\4epmd\21\21u\0\
|
||||
\6remctl\21\25t\0\
|
||||
\6remctl\21\25u\0\
|
||||
\11f5-iquery\21\1t\0\
|
||||
\11f5-iquery\21\1u\0\
|
||||
\3iax\21\331t\0\
|
||||
\3iax\21\331u\0\
|
||||
\3mtn\22\123t\0\
|
||||
\3mtn\22\123u\0\
|
||||
\13radmin-port\23\43t\0\
|
||||
\13radmin-port\23\43u\0\
|
||||
\3rfe\23\212u\0\
|
||||
\3rfe\23\212t\0\
|
||||
\4mmcc\23\272t\0\
|
||||
\4mmcc\23\272u\0\
|
||||
\3sip\23\304t\0\
|
||||
\3sip\23\304u\0\
|
||||
\7sip-tls\23\305t\0\
|
||||
\7sip-tls\23\305u\0\
|
||||
\3aol\24\106t\0\
|
||||
\3aol\24\106u\0\
|
||||
\13xmpp-client\24\146t\1\15jabber-client\
|
||||
\13xmpp-client\24\146u\1\15jabber-client\
|
||||
\13xmpp-server\24\225t\1\15jabber-server\
|
||||
\13xmpp-server\24\225u\1\15jabber-server\
|
||||
\10cfengine\24\274t\0\
|
||||
\10cfengine\24\274u\0\
|
||||
\4mdns\24\351t\0\
|
||||
\4mdns\24\351u\0\
|
||||
\12postgresql\25\70t\1\10postgres\
|
||||
\12postgresql\25\70u\1\10postgres\
|
||||
\7freeciv\25\264t\1\4rptp\
|
||||
\7freeciv\25\264u\0\
|
||||
\4amqp\26\50t\0\
|
||||
\4amqp\26\50u\0\
|
||||
\3ggz\26\70t\0\
|
||||
\3ggz\26\70u\0\
|
||||
\3x11\27\160t\1\5x11-0\
|
||||
\3x11\27\160u\1\5x11-0\
|
||||
\5x11-1\27\161t\0\
|
||||
@@ -320,6 +375,12 @@ static const char _services[] = "\
|
||||
\14gnutella-svc\30\312u\0\
|
||||
\14gnutella-rtr\30\313t\0\
|
||||
\14gnutella-rtr\30\313u\0\
|
||||
\13sge-qmaster\31\54t\1\13sge_qmaster\
|
||||
\13sge-qmaster\31\54u\1\13sge_qmaster\
|
||||
\11sge-execd\31\55t\1\11sge_execd\
|
||||
\11sge-execd\31\55u\1\11sge_execd\
|
||||
\13mysql-proxy\31\56t\0\
|
||||
\13mysql-proxy\31\56u\0\
|
||||
\17afs3-fileserver\33\130t\1\3bbs\
|
||||
\17afs3-fileserver\33\130u\1\3bbs\
|
||||
\15afs3-callback\33\131t\0\
|
||||
@@ -342,12 +403,21 @@ static const char _services[] = "\
|
||||
\13afs3-rmtsys\33\141u\0\
|
||||
\14font-service\33\274t\1\3xfs\
|
||||
\14font-service\33\274u\1\3xfs\
|
||||
\10http-alt\37\220t\1\10webcache\
|
||||
\10http-alt\37\220u\0\
|
||||
\12bacula-dir\43\215t\0\
|
||||
\12bacula-dir\43\215u\0\
|
||||
\11bacula-fd\43\216t\0\
|
||||
\11bacula-fd\43\216u\0\
|
||||
\11bacula-sd\43\217t\0\
|
||||
\11bacula-sd\43\217u\0\
|
||||
\5xmms2\45\303t\0\
|
||||
\5xmms2\45\303u\0\
|
||||
\3nbd\52\71t\0\
|
||||
\14zabbix-agent\47\102t\0\
|
||||
\14zabbix-agent\47\102u\0\
|
||||
\16zabbix-trapper\47\103t\0\
|
||||
\16zabbix-trapper\47\103u\0\
|
||||
\6amanda\47\140t\0\
|
||||
\6amanda\47\140u\0\
|
||||
\3hkp\54\153t\0\
|
||||
@@ -364,16 +434,17 @@ static const char _services[] = "\
|
||||
\4bpcd\65\326u\0\
|
||||
\6vopied\65\327t\0\
|
||||
\6vopied\65\327u\0\
|
||||
\4dcap\126\155t\0\
|
||||
\7gsidcap\126\160t\0\
|
||||
\4wnn6\127\1t\0\
|
||||
\4wnn6\127\1u\0\
|
||||
\11kerberos4\2\356u\2\13kerberos-iv\3kdc\
|
||||
\11kerberos4\2\356t\2\13kerberos-iv\3kdc\
|
||||
\17kerberos_master\2\357u\0\
|
||||
\17kerberos_master\2\357t\0\
|
||||
\15passwd_server\2\360u\0\
|
||||
\10krb_prop\2\362t\2\11krb5_prop\5hprop\
|
||||
\17kerberos-master\2\357u\1\17kerberos_master\
|
||||
\17kerberos-master\2\357t\0\
|
||||
\15passwd-server\2\360u\1\15passwd_server\
|
||||
\10krb-prop\2\362t\3\10krb_prop\11krb5_prop\5hprop\
|
||||
\11krbupdate\2\370t\1\4kreg\
|
||||
\7kpasswd\2\371t\1\4kpwd\
|
||||
\4swat\3\205t\0\
|
||||
\4kpop\4\125t\0\
|
||||
\5knetd\10\5t\0\
|
||||
@@ -389,9 +460,9 @@ static const char _services[] = "\
|
||||
\10poppassd\0\152t\0\
|
||||
\10poppassd\0\152u\0\
|
||||
\5ssmtp\1\321t\1\5smtps\
|
||||
\10moira_db\3\7t\0\
|
||||
\14moira_update\3\11t\0\
|
||||
\12moira_ureg\3\13u\0\
|
||||
\10moira-db\3\7t\1\10moira_db\
|
||||
\14moira-update\3\11t\1\14moira_update\
|
||||
\12moira-ureg\3\13u\1\12moira_ureg\
|
||||
\5spamd\3\17t\0\
|
||||
\5omirr\3\50t\1\6omirrd\
|
||||
\5omirr\3\50u\1\6omirrd\
|
||||
@@ -404,9 +475,7 @@ static const char _services[] = "\
|
||||
\4xtel\5\41t\0\
|
||||
\5xtelw\5\42t\0\
|
||||
\7support\5\371t\0\
|
||||
\5sieve\7\320t\0\
|
||||
\7cfinger\7\323t\0\
|
||||
\4ndtp\7\332t\0\
|
||||
\4frox\10\111t\0\
|
||||
\10ninstall\10\146t\0\
|
||||
\10ninstall\10\146u\0\
|
||||
@@ -436,9 +505,7 @@ static const char _services[] = "\
|
||||
\7hostmon\24\353t\0\
|
||||
\7hostmon\24\353u\0\
|
||||
\5rplay\25\263u\0\
|
||||
\5rplay\25\263t\0\
|
||||
\4rptp\25\264u\0\
|
||||
\4rptp\25\264t\0\
|
||||
\4nrpe\26\42t\0\
|
||||
\4nsca\26\43t\0\
|
||||
\4mrtd\26\52t\0\
|
||||
\6bgpsim\26\53t\0\
|
||||
@@ -446,14 +513,15 @@ static const char _services[] = "\
|
||||
\11sane-port\31\246t\2\4sane\5saned\
|
||||
\4ircd\32\13t\0\
|
||||
\10zope-ftp\37\125t\0\
|
||||
\10webcache\37\220t\0\
|
||||
\6tproxy\37\221t\0\
|
||||
\7omniorb\37\230t\0\
|
||||
\7omniorb\37\230u\0\
|
||||
\20clc-build-daemon\43\36t\0\
|
||||
\6xinetd\43\212t\0\
|
||||
\13mandelspawn\44\217u\1\12mandelbrot\
|
||||
\3git\44\312t\0\
|
||||
\4zope\45\311t\0\
|
||||
\6webmin\47\20t\0\
|
||||
\7kamanda\47\141t\0\
|
||||
\7kamanda\47\141u\0\
|
||||
\11amandaidx\47\142t\0\
|
||||
@@ -473,6 +541,7 @@ static const char _services[] = "\
|
||||
\5binkp\137\352t\0\
|
||||
\3asp\152\356t\0\
|
||||
\3asp\152\356u\0\
|
||||
\6csync2\170\221t\0\
|
||||
\11dircproxy\336\250t\0\
|
||||
\5tfido\353\21t\0\
|
||||
\4fido\353\23t\0\
|
||||
|
@@ -1218,6 +1218,7 @@ typedef struct resolv_cache {
|
||||
int max_entries;
|
||||
int num_entries;
|
||||
Entry mru_list;
|
||||
pthread_mutex_t lock;
|
||||
int last_id;
|
||||
Entry* entries;
|
||||
PendingReqInfo pending_requests;
|
||||
@@ -1235,15 +1236,6 @@ struct resolv_cache_info {
|
||||
|
||||
#define HTABLE_VALID(x) ((x) != NULL && (x) != HTABLE_DELETED)
|
||||
|
||||
static pthread_once_t _res_cache_once = PTHREAD_ONCE_INIT;
|
||||
static void _res_cache_init(void);
|
||||
|
||||
// lock protecting everything in the _resolve_cache_info structs (next ptr, etc)
|
||||
static pthread_mutex_t _res_cache_list_lock;
|
||||
|
||||
/* gets cache associated with a network, or NULL if none exists */
|
||||
static struct resolv_cache* _find_named_cache_locked(unsigned netid);
|
||||
|
||||
static void
|
||||
_cache_flush_pending_requests_locked( struct resolv_cache* cache )
|
||||
{
|
||||
@@ -1264,18 +1256,18 @@ _cache_flush_pending_requests_locked( struct resolv_cache* cache )
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 0 if no pending request is found matching the key.
|
||||
* If a matching request is found the calling thread will wait until
|
||||
* the matching request completes, then update *cache and return 1. */
|
||||
/* return 0 if no pending request is found matching the key
|
||||
* if a matching request is found the calling thread will wait
|
||||
* and return 1 when released */
|
||||
static int
|
||||
_cache_check_pending_request_locked( struct resolv_cache** cache, Entry* key, unsigned netid )
|
||||
_cache_check_pending_request_locked( struct resolv_cache* cache, Entry* key )
|
||||
{
|
||||
struct pending_req_info *ri, *prev;
|
||||
int exist = 0;
|
||||
|
||||
if (*cache && key) {
|
||||
ri = (*cache)->pending_requests.next;
|
||||
prev = &(*cache)->pending_requests;
|
||||
if (cache && key) {
|
||||
ri = cache->pending_requests.next;
|
||||
prev = &cache->pending_requests;
|
||||
while (ri) {
|
||||
if (ri->hash == key->hash) {
|
||||
exist = 1;
|
||||
@@ -1296,9 +1288,7 @@ _cache_check_pending_request_locked( struct resolv_cache** cache, Entry* key, un
|
||||
struct timespec ts = {0,0};
|
||||
XLOG("Waiting for previous request");
|
||||
ts.tv_sec = _time_now() + PENDING_REQUEST_TIMEOUT;
|
||||
pthread_cond_timedwait(&ri->cond, &_res_cache_list_lock, &ts);
|
||||
/* Must update *cache as it could have been deleted. */
|
||||
*cache = _find_named_cache_locked(netid);
|
||||
pthread_cond_timedwait(&ri->cond, &cache->lock, &ts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1335,25 +1325,17 @@ _cache_notify_waiting_tid_locked( struct resolv_cache* cache, Entry* key )
|
||||
|
||||
/* notify the cache that the query failed */
|
||||
void
|
||||
_resolv_cache_query_failed( unsigned netid,
|
||||
_resolv_cache_query_failed( struct resolv_cache* cache,
|
||||
const void* query,
|
||||
int querylen)
|
||||
{
|
||||
Entry key[1];
|
||||
Cache* cache;
|
||||
|
||||
if (!entry_init_key(key, query, querylen))
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
cache = _find_named_cache_locked(netid);
|
||||
|
||||
if (cache) {
|
||||
if (cache && entry_init_key(key, query, querylen)) {
|
||||
pthread_mutex_lock(&cache->lock);
|
||||
_cache_notify_waiting_tid_locked(cache, key);
|
||||
pthread_mutex_unlock(&cache->lock);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1409,6 +1391,7 @@ _resolv_cache_create( void )
|
||||
cache->max_entries = _res_cache_get_max_entries();
|
||||
cache->entries = calloc(sizeof(*cache->entries), cache->max_entries);
|
||||
if (cache->entries) {
|
||||
pthread_mutex_init( &cache->lock, NULL );
|
||||
cache->mru_list.mru_prev = cache->mru_list.mru_next = &cache->mru_list;
|
||||
XLOG("%s: cache created\n", __FUNCTION__);
|
||||
} else {
|
||||
@@ -1453,7 +1436,7 @@ _dump_answer(const void* answer, int answerlen)
|
||||
char* buf;
|
||||
int fileLen;
|
||||
|
||||
fp = fopen("/data/reslog.txt", "w+");
|
||||
fp = fopen("/data/reslog.txt", "w+e");
|
||||
if (fp != NULL) {
|
||||
statep = __res_get_state();
|
||||
|
||||
@@ -1603,7 +1586,7 @@ static void _cache_remove_expired(Cache* cache) {
|
||||
}
|
||||
|
||||
ResolvCacheStatus
|
||||
_resolv_cache_lookup( unsigned netid,
|
||||
_resolv_cache_lookup( struct resolv_cache* cache,
|
||||
const void* query,
|
||||
int querylen,
|
||||
void* answer,
|
||||
@@ -1614,7 +1597,6 @@ _resolv_cache_lookup( unsigned netid,
|
||||
Entry** lookup;
|
||||
Entry* e;
|
||||
time_t now;
|
||||
Cache* cache;
|
||||
|
||||
ResolvCacheStatus result = RESOLV_CACHE_NOTFOUND;
|
||||
|
||||
@@ -1627,14 +1609,7 @@ _resolv_cache_lookup( unsigned netid,
|
||||
return RESOLV_CACHE_UNSUPPORTED;
|
||||
}
|
||||
/* lookup cache */
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
cache = _find_named_cache_locked(netid);
|
||||
if (cache == NULL) {
|
||||
result = RESOLV_CACHE_UNSUPPORTED;
|
||||
goto Exit;
|
||||
}
|
||||
pthread_mutex_lock( &cache->lock );
|
||||
|
||||
/* see the description of _lookup_p to understand this.
|
||||
* the function always return a non-NULL pointer.
|
||||
@@ -1646,7 +1621,7 @@ _resolv_cache_lookup( unsigned netid,
|
||||
XLOG( "NOT IN CACHE");
|
||||
// calling thread will wait if an outstanding request is found
|
||||
// that matching this query
|
||||
if (!_cache_check_pending_request_locked(&cache, key, netid) || cache == NULL) {
|
||||
if (!_cache_check_pending_request_locked(cache, key)) {
|
||||
goto Exit;
|
||||
} else {
|
||||
lookup = _cache_lookup_p(cache, key);
|
||||
@@ -1687,13 +1662,13 @@ _resolv_cache_lookup( unsigned netid,
|
||||
result = RESOLV_CACHE_FOUND;
|
||||
|
||||
Exit:
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
pthread_mutex_unlock( &cache->lock );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_resolv_cache_add( unsigned netid,
|
||||
_resolv_cache_add( struct resolv_cache* cache,
|
||||
const void* query,
|
||||
int querylen,
|
||||
const void* answer,
|
||||
@@ -1703,7 +1678,6 @@ _resolv_cache_add( unsigned netid,
|
||||
Entry* e;
|
||||
Entry** lookup;
|
||||
u_long ttl;
|
||||
Cache* cache = NULL;
|
||||
|
||||
/* don't assume that the query has already been cached
|
||||
*/
|
||||
@@ -1712,12 +1686,7 @@ _resolv_cache_add( unsigned netid,
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
cache = _find_named_cache_locked(netid);
|
||||
if (cache == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
pthread_mutex_lock( &cache->lock );
|
||||
|
||||
XLOG( "%s: query:", __FUNCTION__ );
|
||||
XLOG_QUERY(query,querylen);
|
||||
@@ -1763,10 +1732,8 @@ _resolv_cache_add( unsigned netid,
|
||||
_cache_dump_mru(cache);
|
||||
#endif
|
||||
Exit:
|
||||
if (cache != NULL) {
|
||||
_cache_notify_waiting_tid_locked(cache, key);
|
||||
}
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
_cache_notify_waiting_tid_locked(cache, key);
|
||||
pthread_mutex_unlock( &cache->lock );
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -1777,13 +1744,20 @@ Exit:
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static pthread_once_t _res_cache_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
// Head of the list of caches. Protected by _res_cache_list_lock.
|
||||
static struct resolv_cache_info _res_cache_list;
|
||||
|
||||
// lock protecting everything in the _resolve_cache_info structs (next ptr, etc)
|
||||
static pthread_mutex_t _res_cache_list_lock;
|
||||
|
||||
/* insert resolv_cache_info into the list of resolv_cache_infos */
|
||||
static void _insert_cache_info_locked(struct resolv_cache_info* cache_info);
|
||||
/* creates a resolv_cache_info */
|
||||
static struct resolv_cache_info* _create_cache_info( void );
|
||||
/* gets cache associated with a network, or NULL if none exists */
|
||||
static struct resolv_cache* _find_named_cache_locked(unsigned netid);
|
||||
/* gets a resolv_cache_info associated with a network, or NULL if not found */
|
||||
static struct resolv_cache_info* _find_cache_info_locked(unsigned netid);
|
||||
/* look up the named cache, and creates one if needed */
|
||||
@@ -1811,6 +1785,22 @@ _res_cache_init(void)
|
||||
pthread_mutex_init(&_res_cache_list_lock, NULL);
|
||||
}
|
||||
|
||||
struct resolv_cache*
|
||||
__get_res_cache(unsigned netid)
|
||||
{
|
||||
struct resolv_cache *cache;
|
||||
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
/* Does NOT create a cache if it does not exist. */
|
||||
cache = _find_named_cache_locked(netid);
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
XLOG("%s: netid=%u, cache=%p\n", __FUNCTION__, netid, cache);
|
||||
return cache;
|
||||
}
|
||||
|
||||
static struct resolv_cache*
|
||||
_get_res_cache_for_net_locked(unsigned netid)
|
||||
{
|
||||
@@ -1847,36 +1837,12 @@ _flush_cache_for_net_locked(unsigned netid)
|
||||
{
|
||||
struct resolv_cache* cache = _find_named_cache_locked(netid);
|
||||
if (cache) {
|
||||
pthread_mutex_lock(&cache->lock);
|
||||
_cache_flush_locked(cache);
|
||||
pthread_mutex_unlock(&cache->lock);
|
||||
}
|
||||
}
|
||||
|
||||
void _resolv_delete_cache_for_net(unsigned netid)
|
||||
{
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
struct resolv_cache_info* prev_cache_info = &_res_cache_list;
|
||||
|
||||
while (prev_cache_info->next) {
|
||||
struct resolv_cache_info* cache_info = prev_cache_info->next;
|
||||
|
||||
if (cache_info->netid == netid) {
|
||||
prev_cache_info->next = cache_info->next;
|
||||
_cache_flush_locked(cache_info->cache);
|
||||
free(cache_info->cache->entries);
|
||||
free(cache_info->cache);
|
||||
_free_nameservers_locked(cache_info);
|
||||
free(cache_info);
|
||||
break;
|
||||
}
|
||||
|
||||
prev_cache_info = prev_cache_info->next;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
}
|
||||
|
||||
static struct resolv_cache_info*
|
||||
_create_cache_info(void)
|
||||
{
|
||||
@@ -1949,7 +1915,7 @@ _resolv_set_nameservers_for_net(unsigned netid, const char** servers, int numser
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
sprintf(sbuf, "%u", NAMESERVER_PORT);
|
||||
snprintf(sbuf, sizeof(sbuf), "%u", NAMESERVER_PORT);
|
||||
|
||||
index = 0;
|
||||
for (i = 0; i < numservers && i < MAXNS; i++) {
|
||||
|
@@ -126,14 +126,6 @@ __RCSID("$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $");
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
extern const char * const _res_opcodes[];
|
||||
extern const char * const _res_sectioncodes[];
|
||||
|
||||
@@ -588,7 +580,7 @@ sym_ntos(const struct res_sym *syms, int number, int *success) {
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(unname, "%d", number); /* XXX nonreentrant */
|
||||
snprintf(unname, sizeof(unname), "%d", number); /* XXX nonreentrant */
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (unname);
|
||||
@@ -605,7 +597,7 @@ sym_ntop(const struct res_sym *syms, int number, int *success) {
|
||||
return (syms->humanname);
|
||||
}
|
||||
}
|
||||
sprintf(unname, "%d", number); /* XXX nonreentrant */
|
||||
snprintf(unname, sizeof(unname), "%d", number); /* XXX nonreentrant */
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (unname);
|
||||
@@ -625,7 +617,7 @@ p_type(int type) {
|
||||
return (result);
|
||||
if (type < 0 || type > 0xffff)
|
||||
return ("BADTYPE");
|
||||
sprintf(typebuf, "TYPE%d", type);
|
||||
snprintf(typebuf, sizeof(typebuf), "TYPE%d", type);
|
||||
return (typebuf);
|
||||
}
|
||||
|
||||
@@ -661,7 +653,7 @@ p_class(int class) {
|
||||
return (result);
|
||||
if (class < 0 || class > 0xffff)
|
||||
return ("BADCLASS");
|
||||
sprintf(classbuf, "CLASS%d", class);
|
||||
snprintf(classbuf, sizeof(classbuf), "CLASS%d", class);
|
||||
return (classbuf);
|
||||
}
|
||||
|
||||
@@ -703,7 +695,7 @@ p_option(u_long option) {
|
||||
case RES_NO_NIBBLE2: return "no-nibble2";
|
||||
#endif
|
||||
/* XXX nonreentrant */
|
||||
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
|
||||
default: snprintf(nbuf, sizeof(nbuf), "?0x%lx?", (u_long)option);
|
||||
return (nbuf);
|
||||
}
|
||||
}
|
||||
@@ -716,7 +708,7 @@ p_time(u_int32_t value) {
|
||||
static char nbuf[40]; /* XXX nonreentrant */
|
||||
|
||||
if (ns_format_ttl((u_long)value, nbuf, sizeof nbuf) < 0)
|
||||
sprintf(nbuf, "%u", value);
|
||||
snprintf(nbuf, sizeof(nbuf), "%u", value);
|
||||
return (nbuf);
|
||||
}
|
||||
|
||||
@@ -745,7 +737,7 @@ p_sockun(union res_sockaddr_union u, char *buf, size_t size) {
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
sprintf(ret, "[af%d]", u.sin.sin_family);
|
||||
snprintf(ret, sizeof(ret), "[af%d]", u.sin.sin_family);
|
||||
break;
|
||||
}
|
||||
if (size > 0U) {
|
||||
@@ -777,7 +769,7 @@ precsize_ntoa(u_int32_t prec)
|
||||
|
||||
val = mantissa * poweroften[exponent];
|
||||
|
||||
(void) sprintf(retbuf, "%lu.%.2lu", val/100, val%100);
|
||||
(void) snprintf(retbuf, sizeof(retbuf), "%lu.%.2lu", val/100, val%100);
|
||||
return (retbuf);
|
||||
}
|
||||
|
||||
@@ -1028,7 +1020,7 @@ loc_aton(const char *ascii, u_char *binary)
|
||||
|
||||
/* takes an on-the-wire LOC RR and formats it in a human readable format. */
|
||||
const char *
|
||||
loc_ntoa(const u_char *binary, char *ascii)
|
||||
loc_ntoa(const u_char *binary, char *ascii, size_t bufsiz)
|
||||
{
|
||||
static const char *error = "?";
|
||||
static char tmpbuf[sizeof
|
||||
@@ -1055,7 +1047,7 @@ loc_ntoa(const u_char *binary, char *ascii)
|
||||
ascii = tmpbuf;
|
||||
|
||||
if (versionval) {
|
||||
(void) sprintf(ascii, "; error: unknown LOC RR version");
|
||||
(void) snprintf(ascii, bufsiz, "; error: unknown LOC RR version");
|
||||
return (ascii);
|
||||
}
|
||||
|
||||
@@ -1114,7 +1106,7 @@ loc_ntoa(const u_char *binary, char *ascii)
|
||||
hpstr = strdup(precsize_ntoa((u_int32_t)hpval));
|
||||
vpstr = strdup(precsize_ntoa((u_int32_t)vpval));
|
||||
|
||||
sprintf(ascii,
|
||||
snprintf(ascii, bufsiz,
|
||||
"%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm",
|
||||
latdeg, latmin, latsec, latsecfrac, northsouth,
|
||||
longdeg, longmin, longsec, longsecfrac, eastwest,
|
||||
@@ -1180,7 +1172,7 @@ p_secstodate (u_long secs) {
|
||||
#endif
|
||||
mytime->tm_year += 1900;
|
||||
mytime->tm_mon += 1;
|
||||
sprintf(output, "%04d%02d%02d%02d%02d%02d",
|
||||
snprintf(output, sizeof(output), "%04d%02d%02d%02d%02d%02d",
|
||||
mytime->tm_year, mytime->tm_mon, mytime->tm_mday,
|
||||
mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
|
||||
return (output);
|
||||
|
@@ -289,7 +289,7 @@ __res_vinit(res_state statp, int preinit) {
|
||||
line[sizeof(name) - 1] == '\t'))
|
||||
|
||||
nserv = 0;
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) {
|
||||
/* read the config file */
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
/* skip comments */
|
||||
@@ -616,47 +616,6 @@ net_mask(struct in_addr in) /*!< XXX - should really use system's version of thi
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID_CHANGES
|
||||
static int
|
||||
real_randomid(u_int *random_value) {
|
||||
/* open the nonblocking random device, returning -1 on failure */
|
||||
int random_device = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
|
||||
if (random_device < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read from the random device, returning -1 on failure (or too many retries)*/
|
||||
for (u_int retry = 5; retry > 0; retry--) {
|
||||
int retval = read(random_device, random_value, sizeof(u_int));
|
||||
if (retval == sizeof(u_int)) {
|
||||
*random_value &= 0xffff;
|
||||
close(random_device);
|
||||
return 0;
|
||||
} else if ((retval < 0) && (errno != EINTR)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(random_device);
|
||||
return -1;
|
||||
}
|
||||
#endif /* ANDROID_CHANGES */
|
||||
|
||||
u_int
|
||||
res_randomid(void) {
|
||||
#ifdef ANDROID_CHANGES
|
||||
int status = 0;
|
||||
u_int output = 0;
|
||||
status = real_randomid(&output);
|
||||
if (status != -1) {
|
||||
return output;
|
||||
}
|
||||
#endif /* ANDROID_CHANGES */
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
|
||||
}
|
||||
|
||||
/*%
|
||||
* This routine is for closing the socket if a virtual circuit is used and
|
||||
* the program wants to close it. This provides support for endhostent()
|
||||
|
@@ -414,7 +414,7 @@ res_nquerydomain(res_state statp,
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
sprintf(nbuf, "%s.%s", name, domain);
|
||||
snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
|
||||
}
|
||||
return (res_nquery(statp, longname, class, type, answer, anslen));
|
||||
}
|
||||
|
@@ -367,6 +367,7 @@ res_nsend(res_state statp,
|
||||
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
|
||||
char abuf[NI_MAXHOST];
|
||||
#if USE_RESOLV_CACHE
|
||||
struct resolv_cache* cache;
|
||||
ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
|
||||
#endif
|
||||
|
||||
@@ -388,24 +389,24 @@ res_nsend(res_state statp,
|
||||
terrno = ETIMEDOUT;
|
||||
|
||||
#if USE_RESOLV_CACHE
|
||||
int anslen = 0;
|
||||
cache_status = _resolv_cache_lookup(
|
||||
statp->netid, buf, buflen,
|
||||
ans, anssiz, &anslen);
|
||||
// get the cache associated with the network
|
||||
cache = __get_res_cache(statp->netid);
|
||||
if (cache != NULL) {
|
||||
int anslen = 0;
|
||||
cache_status = _resolv_cache_lookup(
|
||||
cache, buf, buflen,
|
||||
ans, anssiz, &anslen);
|
||||
|
||||
if (cache_status == RESOLV_CACHE_FOUND) {
|
||||
return anslen;
|
||||
} else if (cache_status != RESOLV_CACHE_UNSUPPORTED) {
|
||||
// had a cache miss for a known network, so populate the thread private
|
||||
// data so the normal resolve path can do its thing
|
||||
_resolv_populate_res_for_net(statp);
|
||||
if (cache_status == RESOLV_CACHE_FOUND) {
|
||||
return anslen;
|
||||
} else {
|
||||
// had a cache miss for a known network, so populate the thread private
|
||||
// data so the normal resolve path can do its thing
|
||||
_resolv_populate_res_for_net(statp);
|
||||
}
|
||||
}
|
||||
|
||||
if (statp->nscount == 0) {
|
||||
// We have no nameservers configured, so there's no point trying.
|
||||
// Tell the cache the query failed, or any retries and anyone else asking the same
|
||||
// question will block for PENDING_REQUEST_TIMEOUT seconds instead of failing fast.
|
||||
_resolv_cache_query_failed(statp->netid, buf, buflen);
|
||||
errno = ESRCH;
|
||||
return (-1);
|
||||
}
|
||||
@@ -601,7 +602,7 @@ res_nsend(res_state statp,
|
||||
|
||||
#if USE_RESOLV_CACHE
|
||||
if (cache_status == RESOLV_CACHE_NOTFOUND) {
|
||||
_resolv_cache_add(statp->netid, buf, buflen,
|
||||
_resolv_cache_add(cache, buf, buflen,
|
||||
ans, resplen);
|
||||
}
|
||||
#endif
|
||||
@@ -657,13 +658,13 @@ res_nsend(res_state statp,
|
||||
errno = terrno;
|
||||
|
||||
#if USE_RESOLV_CACHE
|
||||
_resolv_cache_query_failed(statp->netid, buf, buflen);
|
||||
_resolv_cache_query_failed(cache, buf, buflen);
|
||||
#endif
|
||||
|
||||
return (-1);
|
||||
fail:
|
||||
#if USE_RESOLV_CACHE
|
||||
_resolv_cache_query_failed(statp->netid, buf, buflen);
|
||||
_resolv_cache_query_failed(cache, buf, buflen);
|
||||
#endif
|
||||
res_nclose(statp);
|
||||
return (-1);
|
||||
@@ -950,7 +951,7 @@ connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int
|
||||
origflags = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, origflags | O_NONBLOCK);
|
||||
|
||||
res = __connect(sock, nsap, salen);
|
||||
res = connect(sock, nsap, salen);
|
||||
if (res < 0 && errno != EINPROGRESS) {
|
||||
res = -1;
|
||||
goto done;
|
||||
@@ -1107,7 +1108,7 @@ send_dg(res_state statp,
|
||||
res_nclose(statp);
|
||||
return (0);
|
||||
}
|
||||
if (__connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) {
|
||||
if (connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) {
|
||||
Aerror(statp, stderr, "connect(dg)", errno, nsap,
|
||||
nsaplen);
|
||||
res_nclose(statp);
|
||||
|
@@ -54,11 +54,11 @@ enum {
|
||||
*/
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD = 0x10,
|
||||
|
||||
/* If opening a library using library_fd read it starting at library_fd_offset.
|
||||
/* When opening library using library_fd read it starting with library_offset
|
||||
* This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
|
||||
*/
|
||||
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET = 0x20,
|
||||
ANDROID_DLEXT_USE_LIBRARY_OFFSET = 0x20,
|
||||
|
||||
/* Mask of valid bits */
|
||||
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
|
||||
@@ -66,7 +66,7 @@ enum {
|
||||
ANDROID_DLEXT_WRITE_RELRO |
|
||||
ANDROID_DLEXT_USE_RELRO |
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD |
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET,
|
||||
ANDROID_DLEXT_USE_LIBRARY_OFFSET,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -75,7 +75,7 @@ typedef struct {
|
||||
size_t reserved_size;
|
||||
int relro_fd;
|
||||
int library_fd;
|
||||
off64_t library_fd_offset;
|
||||
off64_t library_offset;
|
||||
} android_dlextinfo;
|
||||
|
||||
extern void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);
|
||||
|
@@ -518,8 +518,9 @@ typedef enum __ns_cert_types {
|
||||
(cp) += NS_INT32SZ; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#if !defined(__LP64__)
|
||||
/* Annoyingly, LP32 shipped with __ names. */
|
||||
/*
|
||||
* ANSI C identifier hiding for bind's lib/nameser.
|
||||
*/
|
||||
#define ns_msg_getflag __ns_msg_getflag
|
||||
#define ns_get16 __ns_get16
|
||||
#define ns_get32 __ns_get32
|
||||
@@ -563,73 +564,101 @@ typedef enum __ns_cert_types {
|
||||
#define ns_subdomain __ns_subdomain
|
||||
#define ns_makecanon __ns_makecanon
|
||||
#define ns_samename __ns_samename
|
||||
#endif
|
||||
#define ns_newmsg_init __ns_newmsg_init
|
||||
#define ns_newmsg_copy __ns_newmsg_copy
|
||||
#define ns_newmsg_id __ns_newmsg_id
|
||||
#define ns_newmsg_flag __ns_newmsg_flag
|
||||
#define ns_newmsg_q __ns_newmsg_q
|
||||
#define ns_newmsg_rr __ns_newmsg_rr
|
||||
#define ns_newmsg_done __ns_newmsg_done
|
||||
#define ns_rdata_unpack __ns_rdata_unpack
|
||||
#define ns_rdata_equal __ns_rdata_equal
|
||||
#define ns_rdata_refers __ns_rdata_refers
|
||||
|
||||
__BEGIN_DECLS
|
||||
int ns_msg_getflag(ns_msg, int) __LIBC_ABI_PUBLIC__;
|
||||
uint16_t ns_get16(const u_char *) __LIBC_ABI_PUBLIC__;
|
||||
uint32_t ns_get32(const u_char *) __LIBC_ABI_PUBLIC__;
|
||||
void ns_put16(uint16_t, u_char *) __LIBC_ABI_PUBLIC__;
|
||||
void ns_put32(uint32_t, u_char *) __LIBC_ABI_PUBLIC__;
|
||||
int ns_initparse(const u_char *, int, ns_msg *) __LIBC_ABI_PUBLIC__;
|
||||
int ns_skiprr(const u_char *, const u_char *, ns_sect, int) __LIBC_ABI_PUBLIC__;
|
||||
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *) __LIBC_ABI_PUBLIC__;
|
||||
int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *) __LIBC_HIDDEN__;
|
||||
int ns_msg_getflag(ns_msg, int);
|
||||
uint16_t ns_get16(const u_char *);
|
||||
uint32_t ns_get32(const u_char *);
|
||||
void ns_put16(uint16_t, u_char *);
|
||||
void ns_put32(uint32_t, u_char *);
|
||||
int ns_initparse(const u_char *, int, ns_msg *);
|
||||
int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
|
||||
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
|
||||
int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *);
|
||||
int ns_sprintrr(const ns_msg *, const ns_rr *,
|
||||
const char *, const char *, char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
const char *, const char *, char *, size_t);
|
||||
int ns_sprintrrf(const u_char *, size_t, const char *,
|
||||
ns_class, ns_type, u_long, const u_char *,
|
||||
size_t, const char *, const char *,
|
||||
char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
int ns_format_ttl(u_long, char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
int ns_parse_ttl(const char *, u_long *) __LIBC_ABI_PUBLIC__;
|
||||
uint32_t ns_datetosecs(const char *cp, int *errp) __LIBC_ABI_PUBLIC__;
|
||||
int ns_name_ntol(const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
int ns_name_ntop(const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
int ns_name_pton(const char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
int ns_name_pton2(const char *, u_char *, size_t, size_t *) __LIBC_HIDDEN__;
|
||||
char *, size_t);
|
||||
int ns_format_ttl(u_long, char *, size_t);
|
||||
int ns_parse_ttl(const char *, u_long *);
|
||||
uint32_t ns_datetosecs(const char *cp, int *errp);
|
||||
int ns_name_ntol(const u_char *, u_char *, size_t);
|
||||
int ns_name_ntop(const u_char *, char *, size_t);
|
||||
int ns_name_pton(const char *, u_char *, size_t);
|
||||
int ns_name_pton2(const char *, u_char *, size_t, size_t *);
|
||||
int ns_name_unpack(const u_char *, const u_char *,
|
||||
const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
const u_char *, u_char *, size_t);
|
||||
int ns_name_unpack2(const u_char *, const u_char *,
|
||||
const u_char *, u_char *, size_t,
|
||||
size_t *) __LIBC_HIDDEN__;
|
||||
size_t *);
|
||||
int ns_name_pack(const u_char *, u_char *, int,
|
||||
const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;
|
||||
const u_char **, const u_char **);
|
||||
int ns_name_uncompress(const u_char *, const u_char *,
|
||||
const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
const u_char *, char *, size_t);
|
||||
int ns_name_compress(const char *, u_char *, size_t,
|
||||
const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;
|
||||
int ns_name_skip(const u_char **, const u_char *) __LIBC_ABI_PUBLIC__;
|
||||
const u_char **, const u_char **);
|
||||
int ns_name_skip(const u_char **, const u_char *);
|
||||
void ns_name_rollback(const u_char *, const u_char **,
|
||||
const u_char **) __LIBC_ABI_PUBLIC__;
|
||||
const u_char **);
|
||||
int ns_sign(u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t) __LIBC_ABI_PUBLIC__;
|
||||
const u_char *, int, u_char *, int *, time_t);
|
||||
int ns_sign2(u_char *, int *, int, int, void *,
|
||||
const u_char *, int, u_char *, int *, time_t,
|
||||
u_char **, u_char **) __LIBC_ABI_PUBLIC__;
|
||||
ssize_t ns_name_length(ns_nname_ct, size_t) __LIBC_HIDDEN__;
|
||||
int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t) __LIBC_HIDDEN__;
|
||||
int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int) __LIBC_HIDDEN__;
|
||||
int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int) __LIBC_HIDDEN__;
|
||||
int ns_name_labels(ns_nname_ct, size_t) __LIBC_HIDDEN__;
|
||||
u_char **, u_char **);
|
||||
ssize_t ns_name_length(ns_nname_ct, size_t);
|
||||
int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t);
|
||||
int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int);
|
||||
int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int);
|
||||
int ns_name_labels(ns_nname_ct, size_t);
|
||||
int ns_sign_tcp(u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int) __LIBC_ABI_PUBLIC__;
|
||||
ns_tcp_tsig_state *, int);
|
||||
int ns_sign_tcp2(u_char *, int *, int, int,
|
||||
ns_tcp_tsig_state *, int,
|
||||
u_char **, u_char **) __LIBC_ABI_PUBLIC__;
|
||||
u_char **, u_char **);
|
||||
int ns_sign_tcp_init(void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;
|
||||
u_char *ns_find_tsig(u_char *, u_char *) __LIBC_ABI_PUBLIC__;
|
||||
ns_tcp_tsig_state *);
|
||||
u_char *ns_find_tsig(u_char *, u_char *);
|
||||
int ns_verify(u_char *, int *, void *,
|
||||
const u_char *, int, u_char *, int *,
|
||||
time_t *, int) __LIBC_ABI_PUBLIC__;
|
||||
time_t *, int);
|
||||
int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
|
||||
int ns_verify_tcp_init(void *, const u_char *, int,
|
||||
ns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;
|
||||
int ns_samedomain(const char *, const char *) __LIBC_ABI_PUBLIC__;
|
||||
int ns_subdomain(const char *, const char *) __LIBC_ABI_PUBLIC__;
|
||||
int ns_makecanon(const char *, char *, size_t) __LIBC_ABI_PUBLIC__;
|
||||
int ns_samename(const char *, const char *) __LIBC_ABI_PUBLIC__;
|
||||
ns_tcp_tsig_state *);
|
||||
int ns_samedomain(const char *, const char *);
|
||||
int ns_subdomain(const char *, const char *);
|
||||
int ns_makecanon(const char *, char *, size_t);
|
||||
int ns_samename(const char *, const char *);
|
||||
int ns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *);
|
||||
int ns_newmsg_copy(ns_newmsg *, ns_msg *);
|
||||
void ns_newmsg_id(ns_newmsg *handle, uint16_t id);
|
||||
void ns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value);
|
||||
int ns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname,
|
||||
ns_type qtype, ns_class qclass);
|
||||
int ns_newmsg_rr(ns_newmsg *handle, ns_sect sect,
|
||||
ns_nname_ct name, ns_type type,
|
||||
ns_class rr_class, uint32_t ttl,
|
||||
uint16_t rdlen, const u_char *rdata);
|
||||
size_t ns_newmsg_done(ns_newmsg *handle);
|
||||
ssize_t ns_rdata_unpack(const u_char *, const u_char *, ns_type,
|
||||
const u_char *, size_t, u_char *, size_t);
|
||||
int ns_rdata_equal(ns_type,
|
||||
const u_char *, size_t,
|
||||
const u_char *, size_t);
|
||||
int ns_rdata_refers(ns_type,
|
||||
const u_char *, size_t,
|
||||
const u_char *);
|
||||
__END_DECLS
|
||||
|
||||
#ifdef BIND_4_COMPAT
|
||||
|
@@ -64,6 +64,7 @@ enum {
|
||||
RTLD_GLOBAL = 2,
|
||||
#endif
|
||||
RTLD_NOLOAD = 4,
|
||||
RTLD_NODELETE = 0x01000,
|
||||
};
|
||||
|
||||
#if defined (__LP64__)
|
||||
|
@@ -54,29 +54,29 @@ typedef struct {
|
||||
#define DF_BIND_NOW 0x00000008
|
||||
#define DF_STATIC_TLS 0x00000010
|
||||
|
||||
#define DF_1_NOW 0x00000001 // Perform complete relocation processing.
|
||||
#define DF_1_GLOBAL 0x00000002 // implies RTLD_GLOBAL
|
||||
#define DF_1_NOW 0x00000001 /* Perform complete relocation processing. */
|
||||
#define DF_1_GLOBAL 0x00000002 /* implies RTLD_GLOBAL */
|
||||
#define DF_1_GROUP 0x00000004
|
||||
#define DF_1_NODELETE 0x00000008 // implies RTLD_NODELETE
|
||||
#define DF_1_NODELETE 0x00000008 /* implies RTLD_NODELETE */
|
||||
#define DF_1_LOADFLTR 0x00000010
|
||||
#define DF_1_INITFIRST 0x00000020
|
||||
#define DF_1_NOOPEN 0x00000040 // Object can not be used with dlopen(3)
|
||||
#define DF_1_NOOPEN 0x00000040 /* Object can not be used with dlopen(3) */
|
||||
#define DF_1_ORIGIN 0x00000080
|
||||
#define DF_1_DIRECT 0x00000100
|
||||
#define DF_1_TRANS 0x00000200
|
||||
#define DF_1_INTERPOSE 0x00000400
|
||||
#define DF_1_NODEFLIB 0x00000800
|
||||
#define DF_1_NODUMP 0x00001000 // Object cannot be dumped with dldump(3)
|
||||
#define DF_1_NODUMP 0x00001000 /* Object cannot be dumped with dldump(3) */
|
||||
#define DF_1_CONFALT 0x00002000
|
||||
#define DF_1_ENDFILTEE 0x00004000
|
||||
#define DF_1_DISPRELDNE 0x00008000
|
||||
#define DF_1_DISPRELPND 0x00010000
|
||||
#define DF_1_NODIRECT 0x00020000
|
||||
#define DF_1_IGNMULDEF 0x00040000 // Internal use
|
||||
#define DF_1_NOKSYMS 0x00080000 // Internal use
|
||||
#define DF_1_NOHDR 0x00100000 // Internal use
|
||||
#define DF_1_IGNMULDEF 0x00040000 /* Internal use */
|
||||
#define DF_1_NOKSYMS 0x00080000 /* Internal use */
|
||||
#define DF_1_NOHDR 0x00100000 /* Internal use */
|
||||
#define DF_1_EDITED 0x00200000
|
||||
#define DF_1_NORELOC 0x00400000 // Internal use
|
||||
#define DF_1_NORELOC 0x00400000 /* Internal use */
|
||||
#define DF_1_SYMINTPOSE 0x00800000
|
||||
#define DF_1_GLOBAUDIT 0x01000000
|
||||
#define DF_1_SINGLETON 0x02000000
|
||||
@@ -109,4 +109,7 @@ typedef struct {
|
||||
#define STT_LOPROC 13
|
||||
#define STT_HIPROC 15
|
||||
|
||||
/* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */
|
||||
#define NT_FPREGSET NT_PRFPREG
|
||||
|
||||
#endif /* _ELF_H */
|
||||
|
@@ -39,20 +39,14 @@
|
||||
__BEGIN_DECLS
|
||||
|
||||
#ifdef __LP64__
|
||||
/* LP64 kernels don't have flock64 because their flock is 64-bit. */
|
||||
struct flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
off64_t l_start;
|
||||
off64_t l_len;
|
||||
pid_t l_pid;
|
||||
};
|
||||
/* LP64 kernels don't have F_*64 defines because their flock is 64-bit. */
|
||||
#define F_GETLK64 F_GETLK
|
||||
#define F_SETLK64 F_SETLK
|
||||
#define F_SETLKW64 F_SETLKW
|
||||
#endif
|
||||
|
||||
#define O_ASYNC FASYNC
|
||||
#define O_RSYNC O_SYNC
|
||||
|
||||
#define SPLICE_F_MOVE 1
|
||||
#define SPLICE_F_NONBLOCK 2
|
||||
|
@@ -25,34 +25,11 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FEATURES_H_
|
||||
#define _FEATURES_H_
|
||||
|
||||
/* certain Linux-specific programs expect a <features.h> header file
|
||||
* that defines various features macros
|
||||
*/
|
||||
|
||||
/* we do include a number of BSD extensions */
|
||||
#define _BSD_SOURCE 1
|
||||
|
||||
/* we do include a number of GNU extensions */
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
/* C95 support */
|
||||
#undef __USE_ISOC95
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L
|
||||
# define __USE_ISOC95 1
|
||||
#endif
|
||||
|
||||
/* C99 support */
|
||||
#undef __USE_ISOC99
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __USE_ISOC99 1
|
||||
#endif
|
||||
|
||||
/* Posix support */
|
||||
#define __USE_POSIX 1
|
||||
#define __USE_POSIX2 1
|
||||
#define __USE_XPG 1
|
||||
/* Our <features.h> macro fun is all in <sys/cdefs.h>. */
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#endif /* _FEATURES_H_ */
|
||||
|
@@ -25,6 +25,7 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBGEN_H
|
||||
#define _LIBGEN_H
|
||||
|
||||
@@ -33,8 +34,18 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* On Android these don't modify their input, and use thread-local storage for their results. */
|
||||
#if !defined(__bionic_using_gnu_basename)
|
||||
/*
|
||||
* <string.h> gets you the GNU basename.
|
||||
* <libgen.h> the POSIX one.
|
||||
* Note that our "POSIX" one has the wrong argument cv-qualifiers, but doesn't
|
||||
* modify its input and uses thread-local storage for the result if necessary.
|
||||
*/
|
||||
extern char* basename(const char*);
|
||||
#define __bionic_using_posix_basename
|
||||
#endif
|
||||
|
||||
/* This has the wrong argument cv-qualifiers, but doesn't modify its input and uses thread-local storage for the result if necessary. */
|
||||
extern char* dirname(const char*);
|
||||
|
||||
#if !defined(__LP64__)
|
||||
|
@@ -37,39 +37,6 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if __POSIX_VISIBLE
|
||||
#define _POSIX_ARG_MAX 4096
|
||||
#define _POSIX_CHILD_MAX 25
|
||||
#define _POSIX_LINK_MAX 8
|
||||
#define _POSIX_MAX_CANON 255
|
||||
#define _POSIX_MAX_INPUT 255
|
||||
#define _POSIX_NAME_MAX 14
|
||||
#define _POSIX_NGROUPS_MAX 0
|
||||
#define _POSIX_OPEN_MAX 16
|
||||
#define _POSIX_PATH_MAX 256
|
||||
#define _POSIX_PIPE_BUF 512
|
||||
#define _POSIX_RE_DUP_MAX 255
|
||||
#define _POSIX_SSIZE_MAX 32767
|
||||
#define _POSIX_STREAM_MAX 8
|
||||
#define _POSIX_SYMLINK_MAX 255
|
||||
#define _POSIX_SYMLOOP_MAX 8
|
||||
#define _POSIX_TZNAME_MAX 3
|
||||
|
||||
#define _POSIX2_BC_BASE_MAX 99
|
||||
#define _POSIX2_BC_DIM_MAX 2048
|
||||
#define _POSIX2_BC_SCALE_MAX 99
|
||||
#define _POSIX2_BC_STRING_MAX 1000
|
||||
#define _POSIX2_COLL_WEIGHTS_MAX 2
|
||||
#define _POSIX2_EXPR_NEST_MAX 32
|
||||
#define _POSIX2_LINE_MAX 2048
|
||||
#define _POSIX2_RE_DUP_MAX _POSIX_RE_DUP_MAX
|
||||
|
||||
#if __POSIX_VISIBLE >= 200112
|
||||
#define _POSIX_TTY_NAME_MAX 9 /* includes trailing NUL */
|
||||
#define _POSIX_LOGIN_NAME_MAX 9 /* includes trailing NUL */
|
||||
#endif /* __POSIX_VISIBLE >= 200112 */
|
||||
#endif /* __POSIX_VISIBLE */
|
||||
|
||||
#if __XPG_VISIBLE
|
||||
#define PASS_MAX 128 /* _PASSWORD_LEN from <pwd.h> */
|
||||
|
||||
@@ -125,4 +92,9 @@
|
||||
/* glibc's PAGE_MASK is the bitwise negation of BSD's! TODO: remove? */
|
||||
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
||||
|
||||
#define SEM_VALUE_MAX 0x3fffffff
|
||||
|
||||
/* POSIX says these belong in <unistd.h> but BSD has some in <limits.h>. */
|
||||
#include <machine/posix_limits.h>
|
||||
|
||||
#endif /* !_LIMITS_H_ */
|
||||
|
73
libc/include/machine/posix_limits.h
Normal file
73
libc/include/machine/posix_limits.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _POSIX_LIMITS_H_
|
||||
#define _POSIX_LIMITS_H_
|
||||
|
||||
/* TODO: complete and check these. */
|
||||
#define _POSIX2_LINE_MAX 2048
|
||||
#define _POSIX2_RE_DUP_MAX _POSIX_RE_DUP_MAX
|
||||
#define _POSIX_ARG_MAX 4096
|
||||
#define _POSIX_CHILD_MAX 25
|
||||
#define _POSIX_CHOWN_RESTRICTED 1 /* yes, chown requires appropriate privileges */
|
||||
#define _POSIX_FSYNC 1 /* fdatasync() supported */
|
||||
#define _POSIX_JOB_CONTROL 1 /* job control is a Linux feature */
|
||||
#define _POSIX_LINK_MAX 8
|
||||
#define _POSIX_LOGIN_NAME_MAX 9 /* includes trailing NUL */
|
||||
#define _POSIX_MAPPED_FILES 1 /* mmap-ed files supported */
|
||||
#define _POSIX_MAX_CANON 255
|
||||
#define _POSIX_MAX_INPUT 255
|
||||
#define _POSIX_MONOTONIC_CLOCK 0 /* the monotonic clock may be available; ask sysconf */
|
||||
#define _POSIX_NAME_MAX 14
|
||||
#define _POSIX_NGROUPS_MAX 0
|
||||
#define _POSIX_NO_TRUNC 1 /* very long pathnames generate an error */
|
||||
#define _POSIX_OPEN_MAX 16
|
||||
#define _POSIX_PATH_MAX 256
|
||||
#define _POSIX_PIPE_BUF 512
|
||||
#define _POSIX_PRIORITY_SCHEDULING 1 /* priority scheduling is a Linux feature */
|
||||
#define _POSIX_REALTIME_SIGNALS -1 /* for now, this is not supported */
|
||||
#define _POSIX_RE_DUP_MAX 255
|
||||
#define _POSIX_SAVED_IDS 1 /* saved user ids is a Linux feature */
|
||||
#define _POSIX_SEMAPHORES 200809L
|
||||
#define _POSIX_SEM_VALUE_MAX 32767
|
||||
#define _POSIX_SSIZE_MAX 32767
|
||||
#define _POSIX_STREAM_MAX 8
|
||||
#define _POSIX_SYMLINK_MAX 255
|
||||
#define _POSIX_SYMLOOP_MAX 8
|
||||
#define _POSIX_SYNCHRONIZED_IO 1 /* synchronized i/o supported */
|
||||
#define _POSIX_THREAD_PRIO_INHERIT 200112L /* linux feature */
|
||||
#define _POSIX_THREAD_PRIO_PROTECT 200112L /* linux feature */
|
||||
#define _POSIX_THREADS 1 /* we support threads */
|
||||
#define _POSIX_THREAD_STACKADDR 1 /* we support thread stack address */
|
||||
#define _POSIX_THREAD_STACKSIZE 1 /* we support thread stack size */
|
||||
#define _POSIX_TIMERS 1 /* Posix timers are supported */
|
||||
#define _POSIX_TTY_NAME_MAX 9 /* includes trailing NUL */
|
||||
#define _POSIX_TZNAME_MAX 3
|
||||
#define _POSIX_VDISABLE '\0'
|
||||
|
||||
#endif /* _POSIX_LIMITS_H_ */
|
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@@ -53,6 +54,27 @@ struct mallinfo {
|
||||
|
||||
extern struct mallinfo mallinfo(void);
|
||||
|
||||
/*
|
||||
* XML structure for malloc_info(3) is in the following format:
|
||||
*
|
||||
* <malloc version="jemalloc-1">
|
||||
* <heap nr="INT">
|
||||
* <allocated-large>INT</allocated-large>
|
||||
* <allocated-huge>INT</allocated-huge>
|
||||
* <allocated-bins>INT</allocated-bins>
|
||||
* <bins-total>INT</bins-total>
|
||||
* <bin nr="INT">
|
||||
* <allocated>INT</allocated>
|
||||
* <nmalloc>INT</nmalloc>
|
||||
* <ndalloc>INT</ndalloc>
|
||||
* </bin>
|
||||
* <!-- more bins -->
|
||||
* </heap>
|
||||
* <!-- more heaps -->
|
||||
* </malloc>
|
||||
*/
|
||||
extern int malloc_info(int, FILE *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* LIBC_INCLUDE_MALLOC_H_ */
|
||||
|
@@ -206,10 +206,10 @@ int pthread_mutexattr_settype(pthread_mutexattr_t*, int) __nonnull((1));
|
||||
|
||||
int pthread_mutex_destroy(pthread_mutex_t*) __nonnull((1));
|
||||
int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*) __nonnull((1));
|
||||
int pthread_mutex_lock(pthread_mutex_t*) /* __nonnull((1)) */;
|
||||
int pthread_mutex_lock(pthread_mutex_t*) __nonnull((1));
|
||||
int pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec*) __nonnull((1, 2));
|
||||
int pthread_mutex_trylock(pthread_mutex_t*) __nonnull((1));
|
||||
int pthread_mutex_unlock(pthread_mutex_t*) /* __nonnull((1)) */;
|
||||
int pthread_mutex_unlock(pthread_mutex_t*) __nonnull((1));
|
||||
|
||||
int pthread_once(pthread_once_t*, void (*)(void)) __nonnull((1, 2));
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user