mirror of
https://github.com/ARM-software/devlib.git
synced 2025-03-14 05:47:51 +00:00
Compare commits
567 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
5425f4afff | ||
|
fa0d099707 | ||
|
f2e81a8b5b | ||
|
c88a5dbb8b | ||
|
1da260b897 | ||
|
3e1c928db3 | ||
|
e402fc7544 | ||
|
1ac461ad77 | ||
|
e551b46207 | ||
|
9ec36e9040 | ||
|
eb9e0c9870 | ||
|
ae8149077c | ||
|
1b6c8069bd | ||
|
4431932e0d | ||
|
8af9f1a328 | ||
|
1efcfed63f | ||
|
df1b5ef4a2 | ||
|
facd251edb | ||
|
a3765cc27d | ||
|
20e5bcd2c7 | ||
|
f60fa59ac1 | ||
|
499ea4753c | ||
|
dabee29350 | ||
|
6a6d9f30dd | ||
|
e927e2f2cd | ||
|
d4d9c92ae9 | ||
|
8773c10424 | ||
|
b6da67d12f | ||
|
fb4e155696 | ||
|
b2e19d333b | ||
|
165b87f248 | ||
|
1d6a007bad | ||
|
796b9fc1ef | ||
|
54a5732c61 | ||
|
bbdd2ab67c | ||
|
38d4796e41 | ||
|
de84a08bf8 | ||
|
b7d7b46626 | ||
|
b485484850 | ||
|
d8a09e895c | ||
|
1c52f13e50 | ||
|
14905fb515 | ||
|
d3ca49f245 | ||
|
3e45a2298e | ||
|
3c37bf3de1 | ||
|
52281051b2 | ||
|
7714acc897 | ||
|
f5f06122f3 | ||
|
c9b539f722 | ||
|
a28c6d7ce0 | ||
|
b8292b1f2b | ||
|
94f1812ab2 | ||
|
71d1663b2d | ||
|
492d42dddb | ||
|
7276097d4e | ||
|
6939e5660e | ||
|
ce02f8695f | ||
|
b5f311feff | ||
|
233f76d03a | ||
|
ac4f581f4b | ||
|
c6bd736c82 | ||
|
28b30649f1 | ||
|
5817866ad0 | ||
|
8247ac91e7 | ||
|
228baeb317 | ||
|
1431bebd80 | ||
|
dd84dc7e38 | ||
|
295f1269ed | ||
|
84c0935fb2 | ||
|
598c0c1d3c | ||
|
a1718c3700 | ||
|
b5715b6560 | ||
|
39dfa7ef72 | ||
|
a83fe52382 | ||
|
613b4fabba | ||
|
be7e73db16 | ||
|
e334f8816c | ||
|
38d8053f2f | ||
|
7ccdea6b8e | ||
|
cb36347dfe | ||
|
c60737c78e | ||
|
f60e341d6e | ||
|
46219ace04 | ||
|
4589b4698e | ||
|
56746fdb33 | ||
|
c347861db4 | ||
|
3f9ce8ba73 | ||
|
f30fb0b3fd | ||
|
c39d40c6f8 | ||
|
926aee1833 | ||
|
19c51547d1 | ||
|
52485fbaa5 | ||
|
416e8ac40f | ||
|
ea4eccf95d | ||
|
b8bf2abf3b | ||
|
9f71c818c4 | ||
|
0579a814f1 | ||
|
900531b417 | ||
|
14b4e2069b | ||
|
07294251c8 | ||
|
2f48b84e6b | ||
|
5a1eb4a778 | ||
|
d7d1deedda | ||
|
18d2a343c7 | ||
|
5104002f1a | ||
|
90973cac08 | ||
|
403a0faf93 | ||
|
9199d8884e | ||
|
14bb86efad | ||
|
1c0223556f | ||
|
9b15807c17 | ||
|
86fcc11ae1 | ||
|
b5aa065f7b | ||
|
35e7288149 | ||
|
6b09571859 | ||
|
1730f69461 | ||
|
cf4d3b5f4c | ||
|
eb2c7e488b | ||
|
306fd0624c | ||
|
fe28e086c2 | ||
|
59ff6100d8 | ||
|
be988bb42b | ||
|
ac0c39e31a | ||
|
e6323fc8bf | ||
|
7e2399055b | ||
|
ddaa2f1621 | ||
|
1c5412be2f | ||
|
e0b1176757 | ||
|
45aebdaca9 | ||
|
1239fd922e | ||
|
069d2322f1 | ||
|
7bdd6a0ade | ||
|
27fb0453a3 | ||
|
9e0300b9f2 | ||
|
e0c53d0999 | ||
|
0a910071f8 | ||
|
4b13ee79eb | ||
|
fade6b4247 | ||
|
3d2cdd99c5 | ||
|
e012b175c6 | ||
|
5ea63490a9 | ||
|
d7b38e471d | ||
|
7f778e767d | ||
|
93ada9762d | ||
|
111aa327ce | ||
|
cc3498d315 | ||
|
678822f9e4 | ||
|
be734140b3 | ||
|
b988e245d9 | ||
|
b7ef2dc2e0 | ||
|
492284f46d | ||
|
fefdf29ed8 | ||
|
0ea9c73ec0 | ||
|
2c4b16f280 | ||
|
18ab9f80b0 | ||
|
92f58e4e7a | ||
|
bdf8b88ac7 | ||
|
1da174a438 | ||
|
3c9804a45b | ||
|
3fe105ffb7 | ||
|
9bd76fd8af | ||
|
ef9384d161 | ||
|
ff2268b715 | ||
|
5042f474c2 | ||
|
a585426924 | ||
|
1196e336a5 | ||
|
f525374fbb | ||
|
42e62aed57 | ||
|
f5cfcafb08 | ||
|
7853d2c85c | ||
|
a9fcc75f60 | ||
|
cd8720b901 | ||
|
03569fb01f | ||
|
22f53f117e | ||
|
e0abb9db48 | ||
|
c29d386e81 | ||
|
adad59fdba | ||
|
48329b7891 | ||
|
728b59ad7e | ||
|
2b38548463 | ||
|
bdb04aa8d0 | ||
|
8f80d8a5ee | ||
|
ff599dfbb6 | ||
|
00a5bcb377 | ||
|
fffa040792 | ||
|
7d6ed2dd8a | ||
|
f6bbd2c187 | ||
|
a65189f028 | ||
|
77f0b1f06d | ||
|
b4c76007c8 | ||
|
3f92d92a3f | ||
|
0e0417c6b3 | ||
|
e979bafb50 | ||
|
0c1878786b | ||
|
ff57e785f8 | ||
|
f1c8ca1a66 | ||
|
b719808ef2 | ||
|
477e82c444 | ||
|
173df18f29 | ||
|
79be8bc5ad | ||
|
55d914bf93 | ||
|
528d3d4e0f | ||
|
d6a2ed8247 | ||
|
917800ffa6 | ||
|
5671b49c2f | ||
|
27616813ea | ||
|
cdceba59ba | ||
|
301d43d140 | ||
|
8b92f5530a | ||
|
ad5a97afcc | ||
|
e231cb0849 | ||
|
47280f63da | ||
|
a6dd4ddbce | ||
|
9c8624833e | ||
|
dd7860d477 | ||
|
914a93355a | ||
|
676336a72a | ||
|
b5cd5358ab | ||
|
e6c52c49ff | ||
|
6825130e48 | ||
|
80c0e37d11 | ||
|
f523afda95 | ||
|
b64ec714a0 | ||
|
6249c06b44 | ||
|
3af3463c3c | ||
|
7065847f77 | ||
|
79783fa09a | ||
|
796536d67d | ||
|
b9374d530e | ||
|
34e51e7230 | ||
|
fa595e1a3d | ||
|
78938cf243 | ||
|
4941a7183a | ||
|
3ab9d23a4a | ||
|
5cf18a7b3c | ||
|
5bfeae08f4 | ||
|
a87a1df0fb | ||
|
3bf763688e | ||
|
a5cced85ce | ||
|
9f55ae7603 | ||
|
e7bafd6e5b | ||
|
ca84124fae | ||
|
1f41853341 | ||
|
82a2f7d8b6 | ||
|
2a633b783a | ||
|
b6d1863e77 | ||
|
bbc891341c | ||
|
d14df074ee | ||
|
81f9ee2c50 | ||
|
09d0a0f500 | ||
|
fe2fe3ae04 | ||
|
4859e818fb | ||
|
5d342044a2 | ||
|
d953377ff3 | ||
|
4f2d9fa66d | ||
|
4e44863777 | ||
|
6cabad14d0 | ||
|
31f7c1e8f9 | ||
|
3bc98f855b | ||
|
d2b80ccaf9 | ||
|
552040f390 | ||
|
0d259be01b | ||
|
792101819a | ||
|
3b8317d42e | ||
|
e3da419e5b | ||
|
e251b158b2 | ||
|
c0a5765da5 | ||
|
b32f15bbdb | ||
|
5116d46141 | ||
|
beb3b011bd | ||
|
bf4e242129 | ||
|
b1538fd184 | ||
|
5b37dfc50b | ||
|
a948982700 | ||
|
d300b9e57f | ||
|
81db8200e2 | ||
|
9e9af8c6de | ||
|
5473031ab7 | ||
|
a82db5ed37 | ||
|
1381944e5b | ||
|
822c50273f | ||
|
8f3200679c | ||
|
2cfb076e4c | ||
|
98bc0a31e1 | ||
|
345a9ed199 | ||
|
1fc9f6cc94 | ||
|
4194b1dd5e | ||
|
ef2d1a6fa4 | ||
|
33397649b6 | ||
|
ebf1c1a2e1 | ||
|
1d1ba7811d | ||
|
dc7faf46e4 | ||
|
0498017bf0 | ||
|
b2950686a7 | ||
|
f2b5f85dab | ||
|
c0f26e536a | ||
|
1a02f77fdd | ||
|
117686996b | ||
|
8695344969 | ||
|
f23fbd22b6 | ||
|
24e6de67ae | ||
|
07bbf902ba | ||
|
590069f01f | ||
|
bef1ec3afc | ||
|
0c72763d2a | ||
|
2129d85422 | ||
|
80bddf38a2 | ||
|
00f3f5f690 | ||
|
bc9478c324 | ||
|
9a2c413372 | ||
|
3cb2793e51 | ||
|
1ad2e895b3 | ||
|
3d5a164338 | ||
|
af8c47151e | ||
|
20d1eabaf0 | ||
|
45ee68fdd4 | ||
|
b52462440c | ||
|
bae741dc81 | ||
|
b717deb8e4 | ||
|
ccde9de257 | ||
|
c25852b210 | ||
|
f7b7aaf527 | ||
|
569e4bd057 | ||
|
07cad78046 | ||
|
21cb10f550 | ||
|
d2aea077b4 | ||
|
d464053546 | ||
|
cfb28c47c0 | ||
|
b941c6c5a6 | ||
|
ea9f9c878b | ||
|
4f10387688 | ||
|
a4f9231707 | ||
|
3c85738f0d | ||
|
45881b9f0d | ||
|
a8ff622f33 | ||
|
fcd2439b50 | ||
|
3709e06b5c | ||
|
7c8573a416 | ||
|
6f1ffee2b7 | ||
|
7ade1b8bcc | ||
|
3c28c280de | ||
|
b9d50ec164 | ||
|
7780cfdd5c | ||
|
7c79a040b7 | ||
|
779b0cbc77 | ||
|
b6cab6467d | ||
|
ec0a5884c0 | ||
|
7f5e0f5b4d | ||
|
7e682ed97d | ||
|
62e24c5764 | ||
|
eb6fa93845 | ||
|
9d5d70564f | ||
|
922686a348 | ||
|
98e2e51d09 | ||
|
92e16ee873 | ||
|
72ded188fa | ||
|
dcab0b3718 | ||
|
37a6b4f96d | ||
|
1ddbb75e74 | ||
|
696dec9b91 | ||
|
17374cf2b4 | ||
|
9661c6bff3 | ||
|
0aeb5bc409 | ||
|
a5640502ac | ||
|
6fe78b4d47 | ||
|
5bda1c0eee | ||
|
0465a75c56 | ||
|
795c0f233f | ||
|
5ff278b133 | ||
|
b72fb470e7 | ||
|
a4fd57f023 | ||
|
cf8ebf6668 | ||
|
15a77a841d | ||
|
9bf9f2dd1b | ||
|
19887de71e | ||
|
baa7ad1650 | ||
|
75621022be | ||
|
01dd80df34 | ||
|
eb0661a6b4 | ||
|
f303d1326b | ||
|
abd88548d2 | ||
|
2a934288eb | ||
|
2bf4d8a433 | ||
|
cf26dee308 | ||
|
e7bd2a5b22 | ||
|
72be3d01f8 | ||
|
745dc9499a | ||
|
6c9f80ff76 | ||
|
182f4e7b3f | ||
|
4df2b9a4c4 | ||
|
aa64951398 | ||
|
0fa91d6c4c | ||
|
0e6280ae31 | ||
|
2650a534f3 | ||
|
c212ef2146 | ||
|
5b5da7c392 | ||
|
3801fe1d67 | ||
|
43673e3fc5 | ||
|
bbe3bb6adb | ||
|
656da00d2a | ||
|
6b0b12d833 | ||
|
56cdc2e6c3 | ||
|
def235064b | ||
|
4d1299d678 | ||
|
d4f3316120 | ||
|
76ef9e0364 | ||
|
249b8336b5 | ||
|
c5d06ee3d6 | ||
|
207291e940 | ||
|
6b72b50c40 | ||
|
c73266c3a9 | ||
|
0d6c6883dd | ||
|
bb1552151a | ||
|
5e69f06d77 | ||
|
9e6cfde832 | ||
|
4fe0b2cb64 | ||
|
b9654c694c | ||
|
ed135febde | ||
|
5d4315c5d2 | ||
|
9982f810e1 | ||
|
5601fdb108 | ||
|
4e36bad2ab | ||
|
72e4443b7d | ||
|
9ddf763650 | ||
|
18830b74da | ||
|
66de30799b | ||
|
156915f26f | ||
|
74edfcbe43 | ||
|
aa62a52ee3 | ||
|
9c86174ff5 | ||
|
ea19235aed | ||
|
e1fb6cf911 | ||
|
d9d187471f | ||
|
c944d34593 | ||
|
964fde2fef | ||
|
988de69b61 | ||
|
ded30eef00 | ||
|
71bd8b10ed | ||
|
986261bc7e | ||
|
dc5f4c6b49 | ||
|
88f8c9e9ac | ||
|
0c434e8a1b | ||
|
5848369846 | ||
|
002ade33a8 | ||
|
2e8d42db79 | ||
|
6b414cc291 | ||
|
0d798f1c4f | ||
|
1325e59b1a | ||
|
f141899dae | ||
|
984556bc8e | ||
|
03a469fc38 | ||
|
2d86474682 | ||
|
ada318f27b | ||
|
b8f7b24790 | ||
|
a9b9938b0f | ||
|
f619f1dd07 | ||
|
ad350c9267 | ||
|
8343794d34 | ||
|
f2bc5dbc14 | ||
|
6f42f67e95 | ||
|
ae7f01fd19 | ||
|
b5f36610ad | ||
|
4c8f2430e2 | ||
|
a8b6e56874 | ||
|
c92756d65a | ||
|
8512f116fc | ||
|
be8b87d559 | ||
|
d76c2d63fe | ||
|
8bfa050226 | ||
|
8871fe3c25 | ||
|
aa50b2d42d | ||
|
ebcb1664e7 | ||
|
0ff8628c9c | ||
|
c0d8a98d90 | ||
|
441eea9897 | ||
|
b0db2067a2 | ||
|
1417e81605 | ||
|
2e81a72b39 | ||
|
22f2c8b663 | ||
|
c2db6c17ab | ||
|
e01a76ef1b | ||
|
9fcca25031 | ||
|
a6b9542f0f | ||
|
413e83f5d6 | ||
|
ac19873423 | ||
|
17d4b22b9f | ||
|
f65130b7c7 | ||
|
5b51c2644e | ||
|
a752f55956 | ||
|
781f9b068d | ||
|
7e79eeb9cb | ||
|
911a9f2ef4 | ||
|
cc0679e40f | ||
|
5dea9f8bcf | ||
|
a9ee41855d | ||
|
c13e3c260b | ||
|
aabb74c8cb | ||
|
a4c22cef71 | ||
|
3da7fbc9dd | ||
|
f2a87ce61c | ||
|
2b6cb264cf | ||
|
7e0e6e8706 | ||
|
4fabcae0b4 | ||
|
3c4a282c29 | ||
|
683da92067 | ||
|
1569be9ba7 | ||
|
f1b7fd184a | ||
|
22a5945460 | ||
|
fbf0875357 | ||
|
b7ab340d33 | ||
|
beb824256d | ||
|
efbf630422 | ||
|
389ec76c1e | ||
|
1f50b0ffc2 | ||
|
ed7f0e56a2 | ||
|
d376bc10ee | ||
|
60c2e7721e | ||
|
5e13a045a3 | ||
|
c4c76ebcf8 | ||
|
bdaea26f6f | ||
|
a3c04fc140 | ||
|
94c1339efd | ||
|
85e0fb08fe | ||
|
74444210e7 | ||
|
da3afeba2e | ||
|
4a4739cefb | ||
|
01c39cfe4c | ||
|
b9b38a20f6 | ||
|
809d987f84 | ||
|
bf1310c278 | ||
|
78de479a43 | ||
|
75332cf14a | ||
|
6089eaf40a | ||
|
fa41bb01d2 | ||
|
8654a6dc2b | ||
|
150fe2b32b | ||
|
f2a88fd1dc | ||
|
b7a04c9ebc | ||
|
5d97c3186b | ||
|
d86d67f49c | ||
|
996ee82f09 | ||
|
61208ce2e0 | ||
|
8cd1470bb8 | ||
|
66be73be3e | ||
|
63d2fb53fc | ||
|
30dc161f12 | ||
|
d6df5c81fd | ||
|
b0463e58d8 | ||
|
512c5f3737 | ||
|
cc0582ef59 | ||
|
ec717e3399 | ||
|
511d478164 | ||
|
d6d322c8ac | ||
|
ae99db3e24 | ||
|
241c7e01bd | ||
|
68b418dac2 | ||
|
df61b2a269 | ||
|
e8a03e00f3 | ||
|
4b5f65699f | ||
|
454b94501c | ||
|
5cb551b315 | ||
|
3b0df282a9 | ||
|
27fc75f74c | ||
|
473f37f1bc | ||
|
ae8db119a9 | ||
|
472c5a3294 | ||
|
8ac89fe9ed |
20
.readthedocs.yml
Normal file
20
.readthedocs.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# .readthedocs.yml
|
||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
# Required
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
# Build documentation in the docs/ directory with Sphinx
|
||||||
|
sphinx:
|
||||||
|
builder: html
|
||||||
|
configuration: doc/conf.py
|
||||||
|
|
||||||
|
# Build the docs in additional formats such as PDF and ePub
|
||||||
|
formats: all
|
||||||
|
|
||||||
|
# Set the version of Python and requirements required to build your docs
|
||||||
|
python:
|
||||||
|
version: 3.7
|
||||||
|
install:
|
||||||
|
- requirements: doc/requirements.txt
|
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2024 Arm Ltd.
|
||||||
|
|
||||||
|
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.
|
10
README.rst
10
README.rst
@ -14,6 +14,16 @@ Installation
|
|||||||
sudo -H pip install devlib
|
sudo -H pip install devlib
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
``devlib`` should install all dependencies automatically, however if you run
|
||||||
|
into issues please ensure you are using that latest version of pip.
|
||||||
|
|
||||||
|
On some systems there may additional steps required to install the dependency
|
||||||
|
``paramiko`` please consult the `module documentation <http://www.paramiko.org/installing.html>`_
|
||||||
|
for more information.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018 ARM Limited
|
# Copyright 2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -13,9 +13,25 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
from devlib.target import Target, LinuxTarget, AndroidTarget, LocalLinuxTarget, ChromeOsTarget
|
'''
|
||||||
from devlib.host import PACKAGE_BIN_DIRECTORY
|
Initializations for devlib module
|
||||||
from devlib.exception import DevlibError, TargetError, HostError, TargetNotRespondingError
|
'''
|
||||||
|
|
||||||
|
from devlib.target import (
|
||||||
|
Target, LinuxTarget, AndroidTarget, LocalLinuxTarget,
|
||||||
|
ChromeOsTarget,
|
||||||
|
)
|
||||||
|
|
||||||
|
from devlib.host import (
|
||||||
|
PACKAGE_BIN_DIRECTORY,
|
||||||
|
LocalConnection,
|
||||||
|
)
|
||||||
|
|
||||||
|
from devlib.exception import (
|
||||||
|
DevlibError, DevlibTransientError, DevlibStableError,
|
||||||
|
TargetError, TargetTransientError, TargetStableError,
|
||||||
|
TargetNotRespondingError, HostError,
|
||||||
|
)
|
||||||
|
|
||||||
from devlib.module import Module, HardRestModule, BootModule, FlashModule
|
from devlib.module import Module, HardRestModule, BootModule, FlashModule
|
||||||
from devlib.module import get_module, register_module
|
from devlib.module import get_module, register_module
|
||||||
@ -34,25 +50,34 @@ from devlib.instrument.hwmon import HwmonInstrument
|
|||||||
from devlib.instrument.monsoon import MonsoonInstrument
|
from devlib.instrument.monsoon import MonsoonInstrument
|
||||||
from devlib.instrument.netstats import NetstatsInstrument
|
from devlib.instrument.netstats import NetstatsInstrument
|
||||||
from devlib.instrument.gem5power import Gem5PowerInstrument
|
from devlib.instrument.gem5power import Gem5PowerInstrument
|
||||||
|
from devlib.instrument.baylibre_acme import (
|
||||||
|
BaylibreAcmeNetworkInstrument,
|
||||||
|
BaylibreAcmeXMLInstrument,
|
||||||
|
BaylibreAcmeLocalInstrument,
|
||||||
|
BaylibreAcmeInstrument,
|
||||||
|
)
|
||||||
|
|
||||||
from devlib.derived import DerivedMeasurements, DerivedMetric
|
from devlib.derived import DerivedMeasurements, DerivedMetric
|
||||||
from devlib.derived.energy import DerivedEnergyMeasurements
|
from devlib.derived.energy import DerivedEnergyMeasurements
|
||||||
from devlib.derived.fps import DerivedGfxInfoStats, DerivedSurfaceFlingerStats
|
from devlib.derived.fps import DerivedGfxInfoStats, DerivedSurfaceFlingerStats
|
||||||
|
|
||||||
from devlib.trace.ftrace import FtraceCollector
|
from devlib.collector.ftrace import FtraceCollector
|
||||||
from devlib.trace.serial_trace import SerialTraceCollector
|
from devlib.collector.perfetto import PerfettoCollector
|
||||||
|
from devlib.collector.perf import PerfCollector
|
||||||
|
from devlib.collector.serial_trace import SerialTraceCollector
|
||||||
|
from devlib.collector.dmesg import DmesgCollector
|
||||||
|
from devlib.collector.logcat import LogcatCollector
|
||||||
|
|
||||||
from devlib.host import LocalConnection
|
|
||||||
from devlib.utils.android import AdbConnection
|
from devlib.utils.android import AdbConnection
|
||||||
from devlib.utils.ssh import SshConnection, TelnetConnection, Gem5Connection
|
from devlib.utils.ssh import SshConnection, TelnetConnection, Gem5Connection
|
||||||
|
from devlib.utils.version import (get_devlib_version as __get_devlib_version,
|
||||||
from devlib.utils.version import get_commit as __get_commit
|
get_commit as __get_commit)
|
||||||
|
|
||||||
|
|
||||||
__version__ = '1.0.0'
|
__version__ = __get_devlib_version()
|
||||||
|
|
||||||
__commit = __get_commit()
|
__commit = __get_commit()
|
||||||
if __commit:
|
if __commit:
|
||||||
__full_version__ = '{}-{}'.format(__version__, __commit)
|
__full_version__ = f'{__version__}+{__commit}'
|
||||||
else:
|
else:
|
||||||
__full_version__ = __version__
|
__full_version__ = __version__
|
||||||
|
284
devlib/_target_runner.py
Normal file
284
devlib/_target_runner.py
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
# Copyright 2024 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Target runner and related classes are implemented here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from platform import machine
|
||||||
|
|
||||||
|
from devlib.exception import (TargetStableError, HostError)
|
||||||
|
from devlib.target import LinuxTarget
|
||||||
|
from devlib.utils.misc import get_subprocess, which
|
||||||
|
from devlib.utils.ssh import SshConnection
|
||||||
|
|
||||||
|
|
||||||
|
class TargetRunner:
|
||||||
|
"""
|
||||||
|
A generic class for interacting with targets runners.
|
||||||
|
|
||||||
|
It mainly aims to provide framework support for QEMU like target runners
|
||||||
|
(e.g., :class:`QEMUTargetRunner`).
|
||||||
|
|
||||||
|
:param target: Specifies type of target per :class:`Target` based classes.
|
||||||
|
:type target: Target
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
target):
|
||||||
|
self.target = target
|
||||||
|
|
||||||
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *_):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SubprocessTargetRunner(TargetRunner):
|
||||||
|
"""
|
||||||
|
Class for providing subprocess support to the target runners.
|
||||||
|
|
||||||
|
:param runner_cmd: The command to start runner process (e.g.,
|
||||||
|
``qemu-system-aarch64 -kernel Image -append "console=ttyAMA0" ...``).
|
||||||
|
:type runner_cmd: list(str)
|
||||||
|
|
||||||
|
:param target: Specifies type of target per :class:`Target` based classes.
|
||||||
|
:type target: Target
|
||||||
|
|
||||||
|
:param connect: Specifies if :class:`TargetRunner` should try to connect
|
||||||
|
target after launching it, defaults to True.
|
||||||
|
:type connect: bool or None
|
||||||
|
|
||||||
|
:param boot_timeout: Timeout for target's being ready for SSH access in
|
||||||
|
seconds, defaults to 60.
|
||||||
|
:type boot_timeout: int or None
|
||||||
|
|
||||||
|
:raises HostError: if it cannot execute runner command successfully.
|
||||||
|
|
||||||
|
:raises TargetStableError: if Target is inaccessible.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
runner_cmd,
|
||||||
|
target,
|
||||||
|
connect=True,
|
||||||
|
boot_timeout=60):
|
||||||
|
super().__init__(target=target)
|
||||||
|
|
||||||
|
self.boot_timeout = boot_timeout
|
||||||
|
|
||||||
|
self.logger.info('runner_cmd: %s', runner_cmd)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.runner_process = get_subprocess(runner_cmd)
|
||||||
|
except Exception as ex:
|
||||||
|
raise HostError(f'Error while running "{runner_cmd}": {ex}') from ex
|
||||||
|
|
||||||
|
if connect:
|
||||||
|
self.wait_boot_complete()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *_):
|
||||||
|
"""
|
||||||
|
Exit routine for contextmanager.
|
||||||
|
|
||||||
|
Ensure ``SubprocessTargetRunner.runner_process`` is terminated on exit.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.terminate()
|
||||||
|
|
||||||
|
def wait_boot_complete(self):
|
||||||
|
"""
|
||||||
|
Wait for target OS to finish boot up and become accessible over SSH in at most
|
||||||
|
``SubprocessTargetRunner.boot_timeout`` seconds.
|
||||||
|
|
||||||
|
:raises TargetStableError: In case of timeout.
|
||||||
|
"""
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
elapsed = 0
|
||||||
|
while self.boot_timeout >= elapsed:
|
||||||
|
try:
|
||||||
|
self.target.connect(timeout=self.boot_timeout - elapsed)
|
||||||
|
self.logger.debug('Target is ready.')
|
||||||
|
return
|
||||||
|
# pylint: disable=broad-except
|
||||||
|
except Exception as ex:
|
||||||
|
self.logger.info('Cannot connect target: %s', ex)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
elapsed = time.time() - start_time
|
||||||
|
|
||||||
|
self.terminate()
|
||||||
|
raise TargetStableError(f'Target is inaccessible for {self.boot_timeout} seconds!')
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
"""
|
||||||
|
Terminate ``SubprocessTargetRunner.runner_process``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.logger.debug('Killing target runner...')
|
||||||
|
self.runner_process.kill()
|
||||||
|
self.runner_process.__exit__(None, None, None)
|
||||||
|
|
||||||
|
|
||||||
|
class NOPTargetRunner(TargetRunner):
|
||||||
|
"""
|
||||||
|
Class for implementing a target runner which does nothing except providing .target attribute.
|
||||||
|
|
||||||
|
:param target: Specifies type of target per :class:`Target` based classes.
|
||||||
|
:type target: Target
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, target):
|
||||||
|
super().__init__(target=target)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *_):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
"""
|
||||||
|
Nothing to terminate for NOP target runners.
|
||||||
|
Defined to be compliant with other runners (e.g., ``SubprocessTargetRunner``).
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class QEMUTargetRunner(SubprocessTargetRunner):
|
||||||
|
"""
|
||||||
|
Class for preparing necessary groundwork for launching a guest OS on QEMU.
|
||||||
|
|
||||||
|
:param qemu_settings: A dictionary which has QEMU related parameters. The full list
|
||||||
|
of QEMU parameters is below:
|
||||||
|
* ``kernel_image``: This is the location of kernel image (e.g., ``Image``) which
|
||||||
|
will be used as target's kernel.
|
||||||
|
|
||||||
|
* ``arch``: Architecture type. Defaults to ``aarch64``.
|
||||||
|
|
||||||
|
* ``cpu_types``: List of CPU ids for QEMU. The list only contains ``cortex-a72`` by
|
||||||
|
default. This parameter is valid for Arm architectures only.
|
||||||
|
|
||||||
|
* ``initrd_image``: This points to the location of initrd image (e.g.,
|
||||||
|
``rootfs.cpio.xz``) which will be used as target's root filesystem if kernel
|
||||||
|
does not include one already.
|
||||||
|
|
||||||
|
* ``mem_size``: Size of guest memory in MiB.
|
||||||
|
|
||||||
|
* ``num_cores``: Number of CPU cores. Guest will have ``2`` cores by default.
|
||||||
|
|
||||||
|
* ``num_threads``: Number of CPU threads. Set to ``2`` by defaults.
|
||||||
|
|
||||||
|
* ``cmdline``: Kernel command line parameter. It only specifies console device in
|
||||||
|
default (i.e., ``console=ttyAMA0``) which is valid for Arm architectures.
|
||||||
|
May be changed to ``ttyS0`` for x86 platforms.
|
||||||
|
|
||||||
|
* ``enable_kvm``: Specifies if KVM will be used as accelerator in QEMU or not.
|
||||||
|
Enabled by default if host architecture matches with target's for improving
|
||||||
|
QEMU performance.
|
||||||
|
:type qemu_settings: Dict
|
||||||
|
|
||||||
|
:param connection_settings: the dictionary to store connection settings
|
||||||
|
of ``Target.connection_settings``, defaults to None.
|
||||||
|
:type connection_settings: Dict or None
|
||||||
|
|
||||||
|
:param make_target: Lambda function for creating :class:`Target` based object.
|
||||||
|
:type make_target: func or None
|
||||||
|
|
||||||
|
:Variable positional arguments: Forwarded to :class:`TargetRunner`.
|
||||||
|
|
||||||
|
:raises FileNotFoundError: if QEMU executable, kernel or initrd image cannot be found.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
qemu_settings,
|
||||||
|
connection_settings=None,
|
||||||
|
make_target=LinuxTarget,
|
||||||
|
**args):
|
||||||
|
|
||||||
|
self.connection_settings = {
|
||||||
|
'host': '127.0.0.1',
|
||||||
|
'port': 8022,
|
||||||
|
'username': 'root',
|
||||||
|
'password': 'root',
|
||||||
|
'strict_host_check': False,
|
||||||
|
}
|
||||||
|
self.connection_settings = {**self.connection_settings, **(connection_settings or {})}
|
||||||
|
|
||||||
|
qemu_args = {
|
||||||
|
'arch': 'aarch64',
|
||||||
|
'cpu_type': 'cortex-a72',
|
||||||
|
'mem_size': 512,
|
||||||
|
'num_cores': 2,
|
||||||
|
'num_threads': 2,
|
||||||
|
'cmdline': 'console=ttyAMA0',
|
||||||
|
'enable_kvm': True,
|
||||||
|
}
|
||||||
|
qemu_args = {**qemu_args, **qemu_settings}
|
||||||
|
|
||||||
|
qemu_executable = f'qemu-system-{qemu_args["arch"]}'
|
||||||
|
qemu_path = which(qemu_executable)
|
||||||
|
if qemu_path is None:
|
||||||
|
raise FileNotFoundError(f'Cannot find {qemu_executable} executable!')
|
||||||
|
|
||||||
|
if qemu_args.get("kernel_image"):
|
||||||
|
if not os.path.exists(qemu_args["kernel_image"]):
|
||||||
|
raise FileNotFoundError(f'{qemu_args["kernel_image"]} does not exist!')
|
||||||
|
else:
|
||||||
|
raise KeyError('qemu_settings must have kernel_image!')
|
||||||
|
|
||||||
|
qemu_cmd = [qemu_path,
|
||||||
|
'-kernel', qemu_args["kernel_image"],
|
||||||
|
'-append', f"'{qemu_args['cmdline']}'",
|
||||||
|
'-m', str(qemu_args["mem_size"]),
|
||||||
|
'-smp', f'cores={qemu_args["num_cores"]},threads={qemu_args["num_threads"]}',
|
||||||
|
'-netdev', f'user,id=net0,hostfwd=tcp::{self.connection_settings["port"]}-:22',
|
||||||
|
'-device', 'virtio-net-pci,netdev=net0',
|
||||||
|
'--nographic',
|
||||||
|
]
|
||||||
|
|
||||||
|
if qemu_args.get("initrd_image"):
|
||||||
|
if not os.path.exists(qemu_args["initrd_image"]):
|
||||||
|
raise FileNotFoundError(f'{qemu_args["initrd_image"]} does not exist!')
|
||||||
|
|
||||||
|
qemu_cmd.extend(['-initrd', qemu_args["initrd_image"]])
|
||||||
|
|
||||||
|
if qemu_args["enable_kvm"]:
|
||||||
|
# Enable KVM accelerator if host and guest architectures match.
|
||||||
|
# Comparison is done based on x86 for the sake of simplicity.
|
||||||
|
if (qemu_args['arch'].startswith('x86') and machine().startswith('x86')) or (
|
||||||
|
qemu_args['arch'].startswith('x86') and machine().startswith('x86')):
|
||||||
|
qemu_cmd.append('--enable-kvm')
|
||||||
|
|
||||||
|
# qemu-system-x86_64 does not support -machine virt as of now.
|
||||||
|
if not qemu_args['arch'].startswith('x86'):
|
||||||
|
qemu_cmd.extend(['-machine', 'virt', '-cpu', qemu_args["cpu_type"]])
|
||||||
|
|
||||||
|
target = make_target(connect=False,
|
||||||
|
conn_cls=SshConnection,
|
||||||
|
connection_settings=self.connection_settings)
|
||||||
|
|
||||||
|
super().__init__(runner_cmd=qemu_cmd,
|
||||||
|
target=target,
|
||||||
|
**args)
|
BIN
devlib/bin/arm/simpleperf
Executable file
BIN
devlib/bin/arm/simpleperf
Executable file
Binary file not shown.
604
devlib/bin/arm64/README.busybox
Normal file
604
devlib/bin/arm64/README.busybox
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
Sources of busybox available at:
|
||||||
|
Git commit: 1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4
|
||||||
|
Git repository: git://git.busybox.net/busybox
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.18.3
|
||||||
|
PRETTY_NAME="Alpine Linux v3.18"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=arm64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/arm64
|
||||||
|
export LISA_HOME=''
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.18
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc make musl-dev linux-headers git)
|
||||||
|
|
||||||
|
download() {
|
||||||
|
git clone git://git.busybox.net/busybox --branch 1_36_stable --depth=1
|
||||||
|
git -C busybox checkout 1_36_1
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd busybox
|
||||||
|
make defconfig
|
||||||
|
|
||||||
|
# We need to generate a defconfig then remove the config, then set them to
|
||||||
|
# the value we want, as there is no make olddefconfig to fixup an edited
|
||||||
|
# config.
|
||||||
|
cat .config | grep -v '\bCONFIG_MODPROBE_SMALL\b' | grep -v '\bCONFIG_STATIC\b' > myconfig
|
||||||
|
|
||||||
|
echo "CONFIG_STATIC=y" >> myconfig
|
||||||
|
# MODPROBE_SMALL=y breaks the return code of insmod. Instead of forwarding
|
||||||
|
# the value from the kernel mod init function, it just returns 1.
|
||||||
|
echo "CONFIG_MODPROBE_SMALL=n" >> myconfig
|
||||||
|
|
||||||
|
cp myconfig .config
|
||||||
|
|
||||||
|
make -j 4 "CROSS_COMPILE=$CROSS_COMPILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v busybox/busybox "$LISA_ARCH_ASSETS/busybox"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
install_readme busybox busybox LICENSE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of busybox/LICENSE):
|
||||||
|
|
||||||
|
--- A note on GPL versions
|
||||||
|
|
||||||
|
BusyBox is distributed under version 2 of the General Public License (included
|
||||||
|
in its entirety, below). Version 2 is the only version of this license which
|
||||||
|
this version of BusyBox (or modified versions derived from this one) may be
|
||||||
|
distributed under.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/arm64/README.libtraceevent
Normal file
811
devlib/bin/arm64/README.libtraceevent
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtraceevent available at:
|
||||||
|
Git commit: 9fe4ddef53288cff64886f75561ec46975a67c33
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=arm64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/arm64
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtraceevent/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/arm64/README.libtracefs
Normal file
811
devlib/bin/arm64/README.libtracefs
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtracefs available at:
|
||||||
|
Git commit: 83323ad8695d3db29cfabdb57bf12a7683119dcb
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=arm64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/arm64
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtracefs/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
667
devlib/bin/arm64/README.trace-cmd
Normal file
667
devlib/bin/arm64/README.trace-cmd
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
Sources of trace-cmd available at:
|
||||||
|
Git commit: 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
Git repository: git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=arm64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/arm64
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of trace-cmd/LICENSES/GPL-2.0):
|
||||||
|
|
||||||
|
Valid-License-Identifier: GPL-2.0
|
||||||
|
Valid-License-Identifier: GPL-2.0-only
|
||||||
|
Valid-License-Identifier: GPL-2.0+
|
||||||
|
Valid-License-Identifier: GPL-2.0-or-later
|
||||||
|
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU General Public License (GPL) version 2 only' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
For 'GNU General Public License (GPL) version 2 or any later version' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0+
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
Binary file not shown.
BIN
devlib/bin/arm64/get_clock_boottime
Executable file
BIN
devlib/bin/arm64/get_clock_boottime
Executable file
Binary file not shown.
BIN
devlib/bin/arm64/perf
Normal file
BIN
devlib/bin/arm64/perf
Normal file
Binary file not shown.
BIN
devlib/bin/arm64/simpleperf
Executable file
BIN
devlib/bin/arm64/simpleperf
Executable file
Binary file not shown.
Binary file not shown.
604
devlib/bin/armeabi/README.busybox
Normal file
604
devlib/bin/armeabi/README.busybox
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
Sources of busybox available at:
|
||||||
|
Git commit: 1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4
|
||||||
|
Git repository: git://git.busybox.net/busybox
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.18.3
|
||||||
|
PRETTY_NAME="Alpine Linux v3.18"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=armeabi
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/armeabi
|
||||||
|
export LISA_HOME=''
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.18
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc make musl-dev linux-headers git)
|
||||||
|
|
||||||
|
download() {
|
||||||
|
git clone git://git.busybox.net/busybox --branch 1_36_stable --depth=1
|
||||||
|
git -C busybox checkout 1_36_1
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd busybox
|
||||||
|
make defconfig
|
||||||
|
|
||||||
|
# We need to generate a defconfig then remove the config, then set them to
|
||||||
|
# the value we want, as there is no make olddefconfig to fixup an edited
|
||||||
|
# config.
|
||||||
|
cat .config | grep -v '\bCONFIG_MODPROBE_SMALL\b' | grep -v '\bCONFIG_STATIC\b' > myconfig
|
||||||
|
|
||||||
|
echo "CONFIG_STATIC=y" >> myconfig
|
||||||
|
# MODPROBE_SMALL=y breaks the return code of insmod. Instead of forwarding
|
||||||
|
# the value from the kernel mod init function, it just returns 1.
|
||||||
|
echo "CONFIG_MODPROBE_SMALL=n" >> myconfig
|
||||||
|
|
||||||
|
cp myconfig .config
|
||||||
|
|
||||||
|
make -j 4 "CROSS_COMPILE=$CROSS_COMPILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v busybox/busybox "$LISA_ARCH_ASSETS/busybox"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
install_readme busybox busybox LICENSE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of busybox/LICENSE):
|
||||||
|
|
||||||
|
--- A note on GPL versions
|
||||||
|
|
||||||
|
BusyBox is distributed under version 2 of the General Public License (included
|
||||||
|
in its entirety, below). Version 2 is the only version of this license which
|
||||||
|
this version of BusyBox (or modified versions derived from this one) may be
|
||||||
|
distributed under.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/armeabi/README.libtraceevent
Normal file
811
devlib/bin/armeabi/README.libtraceevent
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtraceevent available at:
|
||||||
|
Git commit: 9fe4ddef53288cff64886f75561ec46975a67c33
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=armeabi
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/armeabi
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtraceevent/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/armeabi/README.libtracefs
Normal file
811
devlib/bin/armeabi/README.libtracefs
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtracefs available at:
|
||||||
|
Git commit: 83323ad8695d3db29cfabdb57bf12a7683119dcb
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=armeabi
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/armeabi
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtracefs/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
667
devlib/bin/armeabi/README.trace-cmd
Normal file
667
devlib/bin/armeabi/README.trace-cmd
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
Sources of trace-cmd available at:
|
||||||
|
Git commit: 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
Git repository: git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=armeabi
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/armeabi
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of trace-cmd/LICENSES/GPL-2.0):
|
||||||
|
|
||||||
|
Valid-License-Identifier: GPL-2.0
|
||||||
|
Valid-License-Identifier: GPL-2.0-only
|
||||||
|
Valid-License-Identifier: GPL-2.0+
|
||||||
|
Valid-License-Identifier: GPL-2.0-or-later
|
||||||
|
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU General Public License (GPL) version 2 only' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
For 'GNU General Public License (GPL) version 2 or any later version' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0+
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
Binary file not shown.
BIN
devlib/bin/armeabi/get_clock_boottime
Executable file
BIN
devlib/bin/armeabi/get_clock_boottime
Executable file
Binary file not shown.
BIN
devlib/bin/armeabi/perf
Normal file
BIN
devlib/bin/armeabi/perf
Normal file
Binary file not shown.
Binary file not shown.
604
devlib/bin/ppc64le/README.busybox
Normal file
604
devlib/bin/ppc64le/README.busybox
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
Sources of busybox available at:
|
||||||
|
Git commit: 1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4
|
||||||
|
Git repository: git://git.busybox.net/busybox
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.18.3
|
||||||
|
PRETTY_NAME="Alpine Linux v3.18"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=ppc64le
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/ppc64le
|
||||||
|
export LISA_HOME=''
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.18
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc make musl-dev linux-headers git)
|
||||||
|
|
||||||
|
download() {
|
||||||
|
git clone git://git.busybox.net/busybox --branch 1_36_stable --depth=1
|
||||||
|
git -C busybox checkout 1_36_1
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd busybox
|
||||||
|
make defconfig
|
||||||
|
|
||||||
|
# We need to generate a defconfig then remove the config, then set them to
|
||||||
|
# the value we want, as there is no make olddefconfig to fixup an edited
|
||||||
|
# config.
|
||||||
|
cat .config | grep -v '\bCONFIG_MODPROBE_SMALL\b' | grep -v '\bCONFIG_STATIC\b' > myconfig
|
||||||
|
|
||||||
|
echo "CONFIG_STATIC=y" >> myconfig
|
||||||
|
# MODPROBE_SMALL=y breaks the return code of insmod. Instead of forwarding
|
||||||
|
# the value from the kernel mod init function, it just returns 1.
|
||||||
|
echo "CONFIG_MODPROBE_SMALL=n" >> myconfig
|
||||||
|
|
||||||
|
cp myconfig .config
|
||||||
|
|
||||||
|
make -j 4 "CROSS_COMPILE=$CROSS_COMPILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v busybox/busybox "$LISA_ARCH_ASSETS/busybox"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
install_readme busybox busybox LICENSE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of busybox/LICENSE):
|
||||||
|
|
||||||
|
--- A note on GPL versions
|
||||||
|
|
||||||
|
BusyBox is distributed under version 2 of the General Public License (included
|
||||||
|
in its entirety, below). Version 2 is the only version of this license which
|
||||||
|
this version of BusyBox (or modified versions derived from this one) may be
|
||||||
|
distributed under.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/ppc64le/README.libtraceevent
Normal file
811
devlib/bin/ppc64le/README.libtraceevent
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtraceevent available at:
|
||||||
|
Git commit: 9fe4ddef53288cff64886f75561ec46975a67c33
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=ppc64le
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/ppc64le
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtraceevent/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/ppc64le/README.libtracefs
Normal file
811
devlib/bin/ppc64le/README.libtracefs
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtracefs available at:
|
||||||
|
Git commit: 83323ad8695d3db29cfabdb57bf12a7683119dcb
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=ppc64le
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/ppc64le
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtracefs/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
667
devlib/bin/ppc64le/README.trace-cmd
Normal file
667
devlib/bin/ppc64le/README.trace-cmd
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
Sources of trace-cmd available at:
|
||||||
|
Git commit: 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
Git repository: git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=ppc64le
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/ppc64le
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of trace-cmd/LICENSES/GPL-2.0):
|
||||||
|
|
||||||
|
Valid-License-Identifier: GPL-2.0
|
||||||
|
Valid-License-Identifier: GPL-2.0-only
|
||||||
|
Valid-License-Identifier: GPL-2.0+
|
||||||
|
Valid-License-Identifier: GPL-2.0-or-later
|
||||||
|
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU General Public License (GPL) version 2 only' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
For 'GNU General Public License (GPL) version 2 or any later version' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0+
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
BIN
devlib/bin/ppc64le/busybox
Normal file
BIN
devlib/bin/ppc64le/busybox
Normal file
Binary file not shown.
BIN
devlib/bin/ppc64le/trace-cmd
Executable file
BIN
devlib/bin/ppc64le/trace-cmd
Executable file
Binary file not shown.
20
devlib/bin/scripts/devlib-signal-target
Normal file
20
devlib/bin/scripts/devlib-signal-target
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
(
|
||||||
|
# If there is no data dir, it means we are not running as a background
|
||||||
|
# command so we just do nothing
|
||||||
|
if [ -e "$_DEVLIB_BG_CMD_DATA_DIR" ]; then
|
||||||
|
pid_file="$_DEVLIB_BG_CMD_DATA_DIR/pid"
|
||||||
|
# Atomically check if the PID file already exist and make the write
|
||||||
|
# fail if it already does. This way we don't have any race condition
|
||||||
|
# with the Python API, as there is either no PID or the same PID for
|
||||||
|
# the duration of the command
|
||||||
|
set -o noclobber
|
||||||
|
if ! printf "%u\n" $$ > "$pid_file"; then
|
||||||
|
echo "$0 was already called for this command" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
) || exit $?
|
||||||
|
|
||||||
|
# Use exec so that the PID of the command we run is the same as the current $$
|
||||||
|
# PID that we just registered
|
||||||
|
exec "$@"
|
@ -1,5 +1,3 @@
|
|||||||
#!__DEVLIB_SHELL__
|
|
||||||
|
|
||||||
CMD=$1
|
CMD=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
@ -10,6 +8,8 @@ SED=${SED:-$BUSYBOX sed}
|
|||||||
CAT=${CAT:-$BUSYBOX cat}
|
CAT=${CAT:-$BUSYBOX cat}
|
||||||
AWK=${AWK:-$BUSYBOX awk}
|
AWK=${AWK:-$BUSYBOX awk}
|
||||||
PS=${PS:-$BUSYBOX ps}
|
PS=${PS:-$BUSYBOX ps}
|
||||||
|
MOUNT=${MOUNT:-$BUSYBOX mount}
|
||||||
|
PRINTF=${PRINTF:-$BUSYBOX printf}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# CPUFrequency Utility Functions
|
# CPUFrequency Utility Functions
|
||||||
@ -40,9 +40,10 @@ cpufreq_get_all_governors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpufreq_trace_all_frequencies() {
|
cpufreq_trace_all_frequencies() {
|
||||||
FREQS=$($CAT /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq)
|
local TRACEFS=$(get_tracefs_mount_point)
|
||||||
CPU=0; for F in $FREQS; do
|
local FREQS=$($CAT /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq)
|
||||||
echo "cpu_frequency_devlib: state=$F cpu_id=$CPU" > /sys/kernel/debug/tracing/trace_marker
|
local CPU=0; for F in $FREQS; do
|
||||||
|
printf "%s\n" "cpu_frequency_devlib: state=$F cpu_id=$CPU" > $TRACEFS/trace_marker
|
||||||
CPU=$((CPU + 1))
|
CPU=$((CPU + 1))
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -94,10 +95,15 @@ cpuidle_wake_all_cpus() {
|
|||||||
# FTrace Utility Functions
|
# FTrace Utility Functions
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
get_tracefs_mount_point() {
|
||||||
|
get_fs_mount_point tracefs || $PRINTF "%s" '/sys/kernel/debug/tracing'
|
||||||
|
}
|
||||||
|
|
||||||
ftrace_get_function_stats() {
|
ftrace_get_function_stats() {
|
||||||
for CPU in $(ls /sys/kernel/debug/tracing/trace_stat | sed 's/function//'); do
|
local TRACEFS=$(get_tracefs_mount_point)
|
||||||
|
for CPU in $(ls $TRACEFS/trace_stat | sed 's/function//'); do
|
||||||
REPLACE_STRING="s/ Function/\n Function (CPU$CPU)/"
|
REPLACE_STRING="s/ Function/\n Function (CPU$CPU)/"
|
||||||
$CAT /sys/kernel/debug/tracing/trace_stat/function$CPU \
|
$CAT $TRACEFS/trace_stat/function$CPU \
|
||||||
| sed "$REPLACE_STRING"
|
| sed "$REPLACE_STRING"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -148,14 +154,23 @@ cgroups_run_into() {
|
|||||||
# Move this shell into that control group
|
# Move this shell into that control group
|
||||||
echo $$ > $CGPATH/cgroup.procs
|
echo $$ > $CGPATH/cgroup.procs
|
||||||
echo "Moving task into root CGroup ($CGPATH)"
|
echo "Moving task into root CGroup ($CGPATH)"
|
||||||
|
# Check the move actually worked
|
||||||
|
$GREP -E "$$" $CGPATH/cgroup.procs >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: Process was not moved into $CGP"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Execution under specified CGroup
|
# Execution under specified CGroup
|
||||||
else
|
else
|
||||||
|
|
||||||
# Check if the required CGroup exists
|
# Check if the required CGroup exists
|
||||||
$FIND $CGMOUNT -type d -mindepth 1 | \
|
$FIND $CGMOUNT -type d -mindepth 1 | \
|
||||||
$GREP -E "^$CGMOUNT/devlib_cgh[0-9]{1,2}$CGP" &>/dev/null
|
$GREP -E "^$CGMOUNT/devlib_cgh[0-9]{1,2}$CGP" >/dev/null 2>&1
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "ERROR: could not find any $CGP cgroup under $CGMOUNT"
|
echo "ERROR: could not find any $CGP cgroup under $CGMOUNT"
|
||||||
exit 1
|
exit 1
|
||||||
@ -167,8 +182,16 @@ cgroups_run_into() {
|
|||||||
# Move this shell into that control group
|
# Move this shell into that control group
|
||||||
echo $$ > $CGPATH/cgroup.procs
|
echo $$ > $CGPATH/cgroup.procs
|
||||||
echo "Moving task into $CGPATH"
|
echo "Moving task into $CGPATH"
|
||||||
|
# Check the move actually worked
|
||||||
|
$GREP -E "$$" $CGPATH/cgroup.procs >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: Process was not moved into $CGP"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Execute the command
|
# Execute the command
|
||||||
@ -214,7 +237,7 @@ cgroups_freezer_set_state() {
|
|||||||
|
|
||||||
# Set the state of the freezer
|
# Set the state of the freezer
|
||||||
echo $STATE > $SYSFS_ENTRY
|
echo $STATE > $SYSFS_ENTRY
|
||||||
|
|
||||||
# And check it applied cleanly
|
# And check it applied cleanly
|
||||||
for i in `seq 1 10`; do
|
for i in `seq 1 10`; do
|
||||||
[ $($CAT $SYSFS_ENTRY) = $STATE ] && exit 0
|
[ $($CAT $SYSFS_ENTRY) = $STATE ] && exit 0
|
||||||
@ -238,6 +261,19 @@ hotplug_online_all() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Scheduler
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
sched_get_kernel_attributes() {
|
||||||
|
MATCH=${1:-'.*'}
|
||||||
|
[ -d /proc/sys/kernel/ ] || exit 1
|
||||||
|
$GREP '' /proc/sys/kernel/sched_* | \
|
||||||
|
$SED -e 's|/proc/sys/kernel/sched_||' | \
|
||||||
|
$GREP -e "$MATCH"
|
||||||
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Misc
|
# Misc
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -264,68 +300,70 @@ read_tree_values() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_tree_tgz_b64() {
|
||||||
|
BASEPATH=$1
|
||||||
|
MAXDEPTH=$2
|
||||||
|
TMPBASE=$3
|
||||||
|
|
||||||
|
if [ ! -e $BASEPATH ]; then
|
||||||
|
echo "ERROR: $BASEPATH does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $TMPBASE
|
||||||
|
TMP_FOLDER=$($BUSYBOX realpath $($BUSYBOX mktemp -d XXXXXX))
|
||||||
|
|
||||||
|
# 'tar' doesn't work as expected on debugfs, so copy the tree first to
|
||||||
|
# workaround the issue
|
||||||
|
cd $BASEPATH
|
||||||
|
for CUR_FILE in $($BUSYBOX find . -follow -type f -maxdepth $MAXDEPTH); do
|
||||||
|
$BUSYBOX cp --parents $CUR_FILE $TMP_FOLDER/ 2> /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
cd $TMP_FOLDER
|
||||||
|
$BUSYBOX tar cz * 2>/dev/null | $BUSYBOX base64
|
||||||
|
|
||||||
|
# Clean-up the tmp folder since we won't need it any more
|
||||||
|
cd $TMPBASE
|
||||||
|
rm -rf $TMP_FOLDER
|
||||||
|
}
|
||||||
|
|
||||||
|
get_linux_system_id() {
|
||||||
|
kernel=$($BUSYBOX uname -r)
|
||||||
|
hardware=$($BUSYBOX ip a | $BUSYBOX grep 'link/ether' | $BUSYBOX sed 's/://g' | $BUSYBOX awk '{print $2}' | $BUSYBOX tr -d '\n')
|
||||||
|
filesystem=$(ls /dev/disk/by-uuid | $BUSYBOX tr '\n' '-' | $BUSYBOX sed 's/-$//')
|
||||||
|
echo "$hardware/$kernel/$filesystem"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_android_system_id() {
|
||||||
|
kernel=$($BUSYBOX uname -r)
|
||||||
|
hardware=$($BUSYBOX ip a | $BUSYBOX grep 'link/ether' | $BUSYBOX sed 's/://g' | $BUSYBOX awk '{print $2}' | $BUSYBOX tr -d '\n')
|
||||||
|
filesystem=$(content query --uri content://settings/secure --projection value --where "name='android_id'" | $BUSYBOX cut -f2 -d=)
|
||||||
|
echo "$hardware/$kernel/$filesystem"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_fs_mount_point() {
|
||||||
|
local path=$(LC_ALL=C $MOUNT -t "$1" | $SED -n "s/$1 on \(.*\) type $1 .*/\1/p;q")
|
||||||
|
if [ "$path" == "" ]; then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
$PRINTF "%s" "$path"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Main Function Dispatcher
|
# Main Function Dispatcher
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
case $CMD in
|
# Use a function instead of a subshell so "exit 1" works as expected
|
||||||
cpufreq_set_all_frequencies)
|
_command_not_found() {
|
||||||
cpufreq_set_all_frequencies $*
|
|
||||||
;;
|
|
||||||
cpufreq_get_all_frequencies)
|
|
||||||
cpufreq_get_all_frequencies
|
|
||||||
;;
|
|
||||||
cpufreq_set_all_governors)
|
|
||||||
cpufreq_set_all_governors $*
|
|
||||||
;;
|
|
||||||
cpufreq_get_all_governors)
|
|
||||||
cpufreq_get_all_governors
|
|
||||||
;;
|
|
||||||
cpufreq_trace_all_frequencies)
|
|
||||||
cpufreq_trace_all_frequencies $*
|
|
||||||
;;
|
|
||||||
devfreq_set_all_frequencies)
|
|
||||||
devfreq_set_all_frequencies $*
|
|
||||||
;;
|
|
||||||
devfreq_get_all_frequencies)
|
|
||||||
devfreq_get_all_frequencies
|
|
||||||
;;
|
|
||||||
devfreq_set_all_governors)
|
|
||||||
devfreq_set_all_governors $*
|
|
||||||
;;
|
|
||||||
devfreq_get_all_governors)
|
|
||||||
devfreq_get_all_governors
|
|
||||||
;;
|
|
||||||
cpuidle_wake_all_cpus)
|
|
||||||
cpuidle_wake_all_cpus $*
|
|
||||||
;;
|
|
||||||
cgroups_get_attributes)
|
|
||||||
cgroups_get_attributes $*
|
|
||||||
;;
|
|
||||||
cgroups_run_into)
|
|
||||||
cgroups_run_into $*
|
|
||||||
;;
|
|
||||||
cgroups_tasks_move)
|
|
||||||
cgroups_tasks_move $*
|
|
||||||
;;
|
|
||||||
cgroups_tasks_in)
|
|
||||||
cgroups_tasks_in $*
|
|
||||||
;;
|
|
||||||
cgroups_freezer_set_state)
|
|
||||||
cgroups_freezer_set_state $*
|
|
||||||
;;
|
|
||||||
ftrace_get_function_stats)
|
|
||||||
ftrace_get_function_stats
|
|
||||||
;;
|
|
||||||
hotplug_online_all)
|
|
||||||
hotplug_online_all
|
|
||||||
;;
|
|
||||||
read_tree_values)
|
|
||||||
read_tree_values $*
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Command [$CMD] not supported"
|
echo "Command [$CMD] not supported"
|
||||||
exit -1
|
exit 1
|
||||||
esac
|
}
|
||||||
|
# Check the command exists
|
||||||
|
type "$CMD" >/dev/null 2>&1 || _command_not_found
|
||||||
|
|
||||||
|
"$CMD" "$@"
|
||||||
|
|
||||||
# vim: tabstop=4 shiftwidth=4
|
# vim: tabstop=4 shiftwidth=4
|
||||||
|
604
devlib/bin/x86/README.busybox
Normal file
604
devlib/bin/x86/README.busybox
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
Sources of busybox available at:
|
||||||
|
Git commit: 1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4
|
||||||
|
Git repository: git://git.busybox.net/busybox
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.18.3
|
||||||
|
PRETTY_NAME="Alpine Linux v3.18"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86
|
||||||
|
export LISA_HOME=''
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.18
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc make musl-dev linux-headers git)
|
||||||
|
|
||||||
|
download() {
|
||||||
|
git clone git://git.busybox.net/busybox --branch 1_36_stable --depth=1
|
||||||
|
git -C busybox checkout 1_36_1
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd busybox
|
||||||
|
make defconfig
|
||||||
|
|
||||||
|
# We need to generate a defconfig then remove the config, then set them to
|
||||||
|
# the value we want, as there is no make olddefconfig to fixup an edited
|
||||||
|
# config.
|
||||||
|
cat .config | grep -v '\bCONFIG_MODPROBE_SMALL\b' | grep -v '\bCONFIG_STATIC\b' > myconfig
|
||||||
|
|
||||||
|
echo "CONFIG_STATIC=y" >> myconfig
|
||||||
|
# MODPROBE_SMALL=y breaks the return code of insmod. Instead of forwarding
|
||||||
|
# the value from the kernel mod init function, it just returns 1.
|
||||||
|
echo "CONFIG_MODPROBE_SMALL=n" >> myconfig
|
||||||
|
|
||||||
|
cp myconfig .config
|
||||||
|
|
||||||
|
make -j 4 "CROSS_COMPILE=$CROSS_COMPILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v busybox/busybox "$LISA_ARCH_ASSETS/busybox"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
install_readme busybox busybox LICENSE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of busybox/LICENSE):
|
||||||
|
|
||||||
|
--- A note on GPL versions
|
||||||
|
|
||||||
|
BusyBox is distributed under version 2 of the General Public License (included
|
||||||
|
in its entirety, below). Version 2 is the only version of this license which
|
||||||
|
this version of BusyBox (or modified versions derived from this one) may be
|
||||||
|
distributed under.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/x86/README.libtraceevent
Normal file
811
devlib/bin/x86/README.libtraceevent
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtraceevent available at:
|
||||||
|
Git commit: 9fe4ddef53288cff64886f75561ec46975a67c33
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtraceevent/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/x86/README.libtracefs
Normal file
811
devlib/bin/x86/README.libtracefs
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtracefs available at:
|
||||||
|
Git commit: 83323ad8695d3db29cfabdb57bf12a7683119dcb
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtracefs/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
667
devlib/bin/x86/README.trace-cmd
Normal file
667
devlib/bin/x86/README.trace-cmd
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
Sources of trace-cmd available at:
|
||||||
|
Git commit: 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
Git repository: git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of trace-cmd/LICENSES/GPL-2.0):
|
||||||
|
|
||||||
|
Valid-License-Identifier: GPL-2.0
|
||||||
|
Valid-License-Identifier: GPL-2.0-only
|
||||||
|
Valid-License-Identifier: GPL-2.0+
|
||||||
|
Valid-License-Identifier: GPL-2.0-or-later
|
||||||
|
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU General Public License (GPL) version 2 only' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
For 'GNU General Public License (GPL) version 2 or any later version' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0+
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
BIN
devlib/bin/x86/busybox
Executable file
BIN
devlib/bin/x86/busybox
Executable file
Binary file not shown.
BIN
devlib/bin/x86/simpleperf
Executable file
BIN
devlib/bin/x86/simpleperf
Executable file
Binary file not shown.
BIN
devlib/bin/x86/trace-cmd
Executable file
BIN
devlib/bin/x86/trace-cmd
Executable file
Binary file not shown.
604
devlib/bin/x86_64/README.busybox
Normal file
604
devlib/bin/x86_64/README.busybox
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
Sources of busybox available at:
|
||||||
|
Git commit: 1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4
|
||||||
|
Git repository: git://git.busybox.net/busybox
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.18.3
|
||||||
|
PRETTY_NAME="Alpine Linux v3.18"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86_64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86_64
|
||||||
|
export LISA_HOME=''
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.18
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc make musl-dev linux-headers git)
|
||||||
|
|
||||||
|
download() {
|
||||||
|
git clone git://git.busybox.net/busybox --branch 1_36_stable --depth=1
|
||||||
|
git -C busybox checkout 1_36_1
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd busybox
|
||||||
|
make defconfig
|
||||||
|
|
||||||
|
# We need to generate a defconfig then remove the config, then set them to
|
||||||
|
# the value we want, as there is no make olddefconfig to fixup an edited
|
||||||
|
# config.
|
||||||
|
cat .config | grep -v '\bCONFIG_MODPROBE_SMALL\b' | grep -v '\bCONFIG_STATIC\b' > myconfig
|
||||||
|
|
||||||
|
echo "CONFIG_STATIC=y" >> myconfig
|
||||||
|
# MODPROBE_SMALL=y breaks the return code of insmod. Instead of forwarding
|
||||||
|
# the value from the kernel mod init function, it just returns 1.
|
||||||
|
echo "CONFIG_MODPROBE_SMALL=n" >> myconfig
|
||||||
|
|
||||||
|
cp myconfig .config
|
||||||
|
|
||||||
|
make -j 4 "CROSS_COMPILE=$CROSS_COMPILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v busybox/busybox "$LISA_ARCH_ASSETS/busybox"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
install_readme busybox busybox LICENSE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of busybox/LICENSE):
|
||||||
|
|
||||||
|
--- A note on GPL versions
|
||||||
|
|
||||||
|
BusyBox is distributed under version 2 of the General Public License (included
|
||||||
|
in its entirety, below). Version 2 is the only version of this license which
|
||||||
|
this version of BusyBox (or modified versions derived from this one) may be
|
||||||
|
distributed under.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/x86_64/README.libtraceevent
Normal file
811
devlib/bin/x86_64/README.libtraceevent
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtraceevent available at:
|
||||||
|
Git commit: 9fe4ddef53288cff64886f75561ec46975a67c33
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86_64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86_64
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtraceevent/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
811
devlib/bin/x86_64/README.libtracefs
Normal file
811
devlib/bin/x86_64/README.libtracefs
Normal file
@ -0,0 +1,811 @@
|
|||||||
|
Sources of libtracefs available at:
|
||||||
|
Git commit: 83323ad8695d3db29cfabdb57bf12a7683119dcb
|
||||||
|
Git repository: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86_64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86_64
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of libtracefs/LICENSES/LGPL-2.1):
|
||||||
|
|
||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
667
devlib/bin/x86_64/README.trace-cmd
Normal file
667
devlib/bin/x86_64/README.trace-cmd
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
Sources of trace-cmd available at:
|
||||||
|
Git commit: 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
Git repository: git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
|
||||||
|
Build host info:
|
||||||
|
|
||||||
|
NAME="Alpine Linux"
|
||||||
|
ID=alpine
|
||||||
|
VERSION_ID=3.13.6
|
||||||
|
PRETTY_NAME="Alpine Linux v3.13"
|
||||||
|
HOME_URL="https://alpinelinux.org/"
|
||||||
|
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
|
||||||
|
|
||||||
|
|
||||||
|
Build recipe:
|
||||||
|
|
||||||
|
export ARCH=x86_64
|
||||||
|
export LISA_ARCH_ASSETS=/lisa/_assets/binaries/x86_64
|
||||||
|
export LISA_HOME=''
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
ALPINE_VERSION=v3.13
|
||||||
|
ALPINE_BUILD_DEPENDENCIES=(bash gcc git make linux-headers musl-dev pkgconfig)
|
||||||
|
BROKEN_CROSS_COMPILATION=1
|
||||||
|
|
||||||
|
download() {
|
||||||
|
# Official repo lacks some old version tags
|
||||||
|
# git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git
|
||||||
|
# So we use the personal one from Steven Rostedt
|
||||||
|
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
|
||||||
|
|
||||||
|
# Latest available commit after 2.9.1.
|
||||||
|
# 2.9.1 itself require some fixes.
|
||||||
|
git -C trace-cmd checkout 2191498dc35d629003591f727b604120fabbe02d
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
|
||||||
|
git -C libtraceevent checkout libtraceevent-1.1.2
|
||||||
|
|
||||||
|
git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
|
||||||
|
git -C libtracefs checkout libtracefs-1.0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtraceevent() {
|
||||||
|
cd libtraceevent
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libtracefs() {
|
||||||
|
cd libtracefs
|
||||||
|
make install
|
||||||
|
}
|
||||||
|
|
||||||
|
build_tracecmd() {
|
||||||
|
# Disable libaudit, to limit the amount of dependencies
|
||||||
|
cd trace-cmd
|
||||||
|
make LDFLAGS="-static" NO_AUDIT=yes
|
||||||
|
strip "$TRACE_CMD_BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For trace-cmd v2.8.3
|
||||||
|
TRACE_CMD_BIN=tracecmd/trace-cmd
|
||||||
|
|
||||||
|
build() {
|
||||||
|
export PYTHON_VERS=python3
|
||||||
|
|
||||||
|
# Do this while waiting to have the build system working.
|
||||||
|
# https://bugzilla.kernel.org/show_bug.cgi?id=212149
|
||||||
|
# When fixed, replace this by what is adviced in trace-cmd/PACKAGING
|
||||||
|
export prefix="/usr"
|
||||||
|
export INSTALL_PATH="$(pwd)/installed_lib_dir"
|
||||||
|
INCLUDE_PKG_PATH="$(cut -d':' -f1 <<<$(pkg-config --variable pc_path pkg-config))"
|
||||||
|
export PKG_CONFIG="pkg-config --with-path $INSTALL_PATH/$INCLUDE_PKG_PATH --define-variable=prefix=$INSTALL_PATH/$prefix"
|
||||||
|
export CFLAGS="-g -Wall -I$INSTALL_PATH/$prefix/include"
|
||||||
|
export DESTDIR=$INSTALL_PATH
|
||||||
|
|
||||||
|
(build_libtraceevent) && (build_libtracefs) && (build_tracecmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cp -v trace-cmd/"$TRACE_CMD_BIN" "$LISA_ARCH_ASSETS/trace-cmd"
|
||||||
|
|
||||||
|
source "$LISA_HOME/tools/recipes/utils.sh"
|
||||||
|
# According to COPYING, the tools are distributed under GPL-2.0 whereas the
|
||||||
|
# libraries are under LGLP-2.1.
|
||||||
|
# Thus, use GPL-2.0 for trace-cmd and LGLP-2.1 for libtraceevent and
|
||||||
|
# libtracefs.
|
||||||
|
install_readme trace-cmd trace-cmd LICENSES/GPL-2.0
|
||||||
|
install_readme libtraceevent libtraceevent LICENSES/LGPL-2.1
|
||||||
|
install_readme libtracefs libtracefs LICENSES/LGPL-2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Do not use libaudit unless there is a good reason, to avoid build issues in
|
||||||
|
# non-necessary dependencies
|
||||||
|
download_audit() {
|
||||||
|
git clone https://github.com/linux-audit/audit-userspace.git
|
||||||
|
git -C audit-userspace checkout master
|
||||||
|
}
|
||||||
|
|
||||||
|
build_audit() {
|
||||||
|
cd audit-userspace
|
||||||
|
./autogen.sh
|
||||||
|
./configure --disable-shared
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The sources were distributed under the following licence (content of trace-cmd/LICENSES/GPL-2.0):
|
||||||
|
|
||||||
|
Valid-License-Identifier: GPL-2.0
|
||||||
|
Valid-License-Identifier: GPL-2.0-only
|
||||||
|
Valid-License-Identifier: GPL-2.0+
|
||||||
|
Valid-License-Identifier: GPL-2.0-or-later
|
||||||
|
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU General Public License (GPL) version 2 only' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
For 'GNU General Public License (GPL) version 2 or any later version' use:
|
||||||
|
SPDX-License-Identifier: GPL-2.0+
|
||||||
|
or
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
The sources were compiled with musl-libc (content of COPYRIGHT):
|
||||||
|
|
||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Valentin Ochs
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Valentin Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
Binary file not shown.
BIN
devlib/bin/x86_64/simpleperf
Executable file
BIN
devlib/bin/x86_64/simpleperf
Executable file
Binary file not shown.
Binary file not shown.
75
devlib/collector/__init__.py
Normal file
75
devlib/collector/__init__.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# Copyright 2015 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from devlib.utils.types import caseless_string
|
||||||
|
|
||||||
|
class CollectorBase(object):
|
||||||
|
|
||||||
|
def __init__(self, target):
|
||||||
|
self.target = target
|
||||||
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
|
self.output_path = None
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
return CollectorOutput()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.reset()
|
||||||
|
self.start()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
class CollectorOutputEntry(object):
|
||||||
|
|
||||||
|
path_kinds = ['file', 'directory']
|
||||||
|
|
||||||
|
def __init__(self, path, path_kind):
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
path_kind = caseless_string(path_kind)
|
||||||
|
if path_kind not in self.path_kinds:
|
||||||
|
msg = '{} is not a valid path_kind [{}]'
|
||||||
|
raise ValueError(msg.format(path_kind, ' '.join(self.path_kinds)))
|
||||||
|
self.path_kind = path_kind
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.path
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<{} ({})>'.format(self.path, self.path_kind)
|
||||||
|
|
||||||
|
def __fspath__(self):
|
||||||
|
"""Allow using with os.path operations"""
|
||||||
|
return self.path
|
||||||
|
|
||||||
|
|
||||||
|
class CollectorOutput(list):
|
||||||
|
pass
|
321
devlib/collector/dmesg.py
Normal file
321
devlib/collector/dmesg.py
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
# Copyright 2024 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import re
|
||||||
|
from itertools import takewhile
|
||||||
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
|
from devlib.exception import TargetStableError
|
||||||
|
from devlib.utils.misc import memoized
|
||||||
|
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger('dmesg')
|
||||||
|
|
||||||
|
|
||||||
|
class KernelLogEntry(object):
|
||||||
|
"""
|
||||||
|
Entry of the kernel ring buffer.
|
||||||
|
|
||||||
|
:param facility: facility the entry comes from
|
||||||
|
:type facility: str
|
||||||
|
|
||||||
|
:param level: log level
|
||||||
|
:type level: str
|
||||||
|
|
||||||
|
:param timestamp: Timestamp of the entry
|
||||||
|
:type timestamp: datetime.timedelta
|
||||||
|
|
||||||
|
:param msg: Content of the entry
|
||||||
|
:type msg: str
|
||||||
|
|
||||||
|
:param line_nr: Line number at which this entry appeared in the ``dmesg``
|
||||||
|
output. Note that this is not guaranteed to be unique across collectors, as
|
||||||
|
the buffer can be cleared. The timestamp is the only reliable index.
|
||||||
|
:type line_nr: int
|
||||||
|
"""
|
||||||
|
|
||||||
|
_TIMESTAMP_MSG_REGEX = re.compile(r'\[(.*?)\] (.*)')
|
||||||
|
_RAW_LEVEL_REGEX = re.compile(r'<([0-9]+)>(.*)')
|
||||||
|
_PRETTY_LEVEL_REGEX = re.compile(r'\s*([a-z]+)\s*:([a-z]+)\s*:\s*(.*)')
|
||||||
|
|
||||||
|
def __init__(self, facility, level, timestamp, msg, line_nr=0):
|
||||||
|
self.facility = facility
|
||||||
|
self.level = level
|
||||||
|
self.timestamp = timestamp
|
||||||
|
self.msg = msg
|
||||||
|
self.line_nr = line_nr
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_str(cls, line, line_nr=0):
|
||||||
|
"""
|
||||||
|
Parses a "dmesg --decode" output line, formatted as following:
|
||||||
|
kern :err : [3618282.310743] nouveau 0000:01:00.0: systemd-logind[988]: nv50cal_space: -16
|
||||||
|
|
||||||
|
Or the more basic output given by "dmesg -r":
|
||||||
|
<3>[3618282.310743] nouveau 0000:01:00.0: systemd-logind[988]: nv50cal_space: -16
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def parse_raw_level(line):
|
||||||
|
match = cls._RAW_LEVEL_REGEX.match(line)
|
||||||
|
if not match:
|
||||||
|
raise ValueError(f'dmesg entry format not recognized: {line}')
|
||||||
|
level, remainder = match.groups()
|
||||||
|
levels = DmesgCollector.LOG_LEVELS
|
||||||
|
# BusyBox dmesg can output numbers that need to wrap around
|
||||||
|
level = levels[int(level) % len(levels)]
|
||||||
|
return level, remainder
|
||||||
|
|
||||||
|
def parse_pretty_level(line):
|
||||||
|
match = cls._PRETTY_LEVEL_REGEX.match(line)
|
||||||
|
if not match:
|
||||||
|
raise ValueError(f'dmesg entry pretty format not recognized: {line}')
|
||||||
|
facility, level, remainder = match.groups()
|
||||||
|
return facility, level, remainder
|
||||||
|
|
||||||
|
def parse_timestamp_msg(line):
|
||||||
|
match = cls._TIMESTAMP_MSG_REGEX.match(line)
|
||||||
|
if not match:
|
||||||
|
raise ValueError(f'dmesg entry timestamp format not recognized: {line}')
|
||||||
|
timestamp, msg = match.groups()
|
||||||
|
timestamp = timedelta(seconds=float(timestamp.strip()))
|
||||||
|
return timestamp, msg
|
||||||
|
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# If we can parse the raw prio directly, that is a basic line
|
||||||
|
try:
|
||||||
|
level, remainder = parse_raw_level(line)
|
||||||
|
facility = None
|
||||||
|
except ValueError:
|
||||||
|
facility, level, remainder = parse_pretty_level(line)
|
||||||
|
|
||||||
|
timestamp, msg = parse_timestamp_msg(remainder)
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
facility=facility,
|
||||||
|
level=level,
|
||||||
|
timestamp=timestamp,
|
||||||
|
msg=msg.strip(),
|
||||||
|
line_nr=line_nr,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dmesg_output(cls, dmesg_out, error=None):
|
||||||
|
"""
|
||||||
|
Return a generator of :class:`KernelLogEntry` for each line of the
|
||||||
|
output of dmesg command.
|
||||||
|
|
||||||
|
:param error: If ``"raise"`` or ``None``, an exception will be raised
|
||||||
|
if a parsing error occurs. If ``"warn"``, it will be logged at
|
||||||
|
WARNING level. If ``"ignore"``, it will be ignored. If a callable
|
||||||
|
is passed, the exception will be passed to it.
|
||||||
|
:type error: str or None or typing.Callable[[BaseException], None]
|
||||||
|
|
||||||
|
.. note:: The same restrictions on the dmesg output format as for
|
||||||
|
:meth:`from_str` apply.
|
||||||
|
"""
|
||||||
|
for i, line in enumerate(dmesg_out.splitlines()):
|
||||||
|
if line.strip():
|
||||||
|
try:
|
||||||
|
yield cls.from_str(line, line_nr=i)
|
||||||
|
except Exception as e:
|
||||||
|
if error in (None, 'raise'):
|
||||||
|
raise e
|
||||||
|
elif error == 'warn':
|
||||||
|
_LOGGER.warn(f'error while parsing line "{line!r}": {e}')
|
||||||
|
elif error == 'ignore':
|
||||||
|
pass
|
||||||
|
elif callable(error):
|
||||||
|
error(e)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown error handling strategy: {error}')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
facility = self.facility + ': ' if self.facility else ''
|
||||||
|
return '{facility}{level}: [{timestamp}] {msg}'.format(
|
||||||
|
facility=facility,
|
||||||
|
level=self.level,
|
||||||
|
timestamp=self.timestamp.total_seconds(),
|
||||||
|
msg=self.msg,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DmesgCollector(CollectorBase):
|
||||||
|
"""
|
||||||
|
Dmesg output collector.
|
||||||
|
|
||||||
|
:param level: Minimum log level to enable. All levels that are more
|
||||||
|
critical will be collected as well.
|
||||||
|
:type level: str
|
||||||
|
|
||||||
|
:param facility: Facility to record, see dmesg --help for the list.
|
||||||
|
:type level: str
|
||||||
|
|
||||||
|
:param empty_buffer: If ``True``, the kernel dmesg ring buffer will be
|
||||||
|
emptied before starting. Note that this will break nesting of collectors,
|
||||||
|
so it's not recommended unless it's really necessary.
|
||||||
|
:type empty_buffer: bool
|
||||||
|
|
||||||
|
.. warning:: If BusyBox dmesg is used, facility and level will be ignored,
|
||||||
|
and the parsed entries will also lack that information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# taken from "dmesg --help"
|
||||||
|
# This list needs to be ordered by priority
|
||||||
|
LOG_LEVELS = [
|
||||||
|
"emerg", # system is unusable
|
||||||
|
"alert", # action must be taken immediately
|
||||||
|
"crit", # critical conditions
|
||||||
|
"err", # error conditions
|
||||||
|
"warn", # warning conditions
|
||||||
|
"notice", # normal but significant condition
|
||||||
|
"info", # informational
|
||||||
|
"debug", # debug-level messages
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, target, level=LOG_LEVELS[-1], facility='kern', empty_buffer=False, parse_error=None):
|
||||||
|
super(DmesgCollector, self).__init__(target)
|
||||||
|
|
||||||
|
if not target.is_rooted:
|
||||||
|
raise TargetStableError('Cannot collect dmesg on non-rooted target')
|
||||||
|
|
||||||
|
self.output_path = None
|
||||||
|
|
||||||
|
if level not in self.LOG_LEVELS:
|
||||||
|
raise ValueError('level needs to be one of: {}'.format(
|
||||||
|
', '.join(self.LOG_LEVELS)
|
||||||
|
))
|
||||||
|
self.level = level
|
||||||
|
|
||||||
|
# Check if we have a dmesg from a recent util-linux build, rather than
|
||||||
|
# e.g. busybox's dmesg or the one shipped on some Android versions
|
||||||
|
# (toybox). Note: BusyBox dmesg does not support -h, but will still
|
||||||
|
# print the help with an exit code of 1
|
||||||
|
help_ = self.target.execute('dmesg -h', check_exit_code=False)
|
||||||
|
self.basic_dmesg = not all(
|
||||||
|
opt in help_
|
||||||
|
for opt in ('--facility', '--force-prefix', '--decode', '--level')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.facility = facility
|
||||||
|
try:
|
||||||
|
needs_root = target.read_sysctl('kernel.dmesg_restrict')
|
||||||
|
except ValueError:
|
||||||
|
needs_root = True
|
||||||
|
else:
|
||||||
|
needs_root = bool(int(needs_root))
|
||||||
|
self.needs_root = needs_root
|
||||||
|
|
||||||
|
self._begin_timestamp = None
|
||||||
|
self.empty_buffer = empty_buffer
|
||||||
|
self._dmesg_out = None
|
||||||
|
self._parse_error = parse_error
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dmesg_out(self):
|
||||||
|
out = self._dmesg_out
|
||||||
|
if out is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
entry = self.entries[0]
|
||||||
|
except IndexError:
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
i = entry.line_nr
|
||||||
|
return '\n'.join(out.splitlines()[i:])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def entries(self):
|
||||||
|
return self._get_entries(
|
||||||
|
self._dmesg_out,
|
||||||
|
self._begin_timestamp,
|
||||||
|
error=self._parse_error,
|
||||||
|
)
|
||||||
|
|
||||||
|
@memoized
|
||||||
|
def _get_entries(self, dmesg_out, timestamp, error):
|
||||||
|
entries = KernelLogEntry.from_dmesg_output(dmesg_out, error=error)
|
||||||
|
entries = list(entries)
|
||||||
|
if timestamp is None:
|
||||||
|
return entries
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
first = entries[0]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if first.timestamp > timestamp:
|
||||||
|
msg = 'The dmesg ring buffer has ran out of memory or has been cleared and some entries have been lost'
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
return [
|
||||||
|
entry
|
||||||
|
for entry in entries
|
||||||
|
# Only select entries that are more recent than the one at last
|
||||||
|
# reset()
|
||||||
|
if entry.timestamp > timestamp
|
||||||
|
]
|
||||||
|
|
||||||
|
def _get_output(self):
|
||||||
|
levels_list = list(takewhile(
|
||||||
|
lambda level: level != self.level,
|
||||||
|
self.LOG_LEVELS
|
||||||
|
))
|
||||||
|
levels_list.append(self.level)
|
||||||
|
if self.basic_dmesg:
|
||||||
|
cmd = 'dmesg -r'
|
||||||
|
else:
|
||||||
|
cmd = 'dmesg --facility={facility} --force-prefix --decode --level={levels}'.format(
|
||||||
|
levels=','.join(levels_list),
|
||||||
|
facility=self.facility,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._dmesg_out = self.target.execute(cmd, as_root=self.needs_root)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self._dmesg_out = None
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
# If the buffer is emptied on start(), it does not matter as we will
|
||||||
|
# not end up with entries dating from before start()
|
||||||
|
if self.empty_buffer:
|
||||||
|
# Empty the dmesg ring buffer. This requires root in all cases
|
||||||
|
self.target.execute('dmesg -c', as_root=True)
|
||||||
|
else:
|
||||||
|
self._get_output()
|
||||||
|
try:
|
||||||
|
entry = self.entries[-1]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self._begin_timestamp = entry.timestamp
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self._get_output()
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
with open(self.output_path, 'wt') as f:
|
||||||
|
f.write((self.dmesg_out or '') + '\n')
|
||||||
|
return CollectorOutput([CollectorOutputEntry(self.output_path, 'file')])
|
535
devlib/collector/ftrace.py
Normal file
535
devlib/collector/ftrace.py
Normal file
@ -0,0 +1,535 @@
|
|||||||
|
# Copyright 2015-2018 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import contextlib
|
||||||
|
from shlex import quote
|
||||||
|
import signal
|
||||||
|
|
||||||
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
|
from devlib.host import PACKAGE_BIN_DIRECTORY
|
||||||
|
from devlib.exception import TargetStableError, HostError
|
||||||
|
from devlib.utils.misc import check_output, which, memoized
|
||||||
|
from devlib.utils.asyn import asyncf
|
||||||
|
|
||||||
|
|
||||||
|
TRACE_MARKER_START = 'TRACE_MARKER_START'
|
||||||
|
TRACE_MARKER_STOP = 'TRACE_MARKER_STOP'
|
||||||
|
OUTPUT_TRACE_FILE = 'trace.dat'
|
||||||
|
OUTPUT_PROFILE_FILE = 'trace_stat.dat'
|
||||||
|
DEFAULT_EVENTS = [
|
||||||
|
'cpu_frequency',
|
||||||
|
'cpu_idle',
|
||||||
|
'sched_migrate_task',
|
||||||
|
'sched_process_exec',
|
||||||
|
'sched_process_fork',
|
||||||
|
'sched_stat_iowait',
|
||||||
|
'sched_switch',
|
||||||
|
'sched_wakeup',
|
||||||
|
'sched_wakeup_new',
|
||||||
|
]
|
||||||
|
TIMEOUT = 180
|
||||||
|
|
||||||
|
# Regexps for parsing of function profiling data
|
||||||
|
CPU_RE = re.compile(r' Function \(CPU([0-9]+)\)')
|
||||||
|
STATS_RE = re.compile(r'([^ ]*) +([0-9]+) +([0-9.]+) us +([0-9.]+) us +([0-9.]+) us')
|
||||||
|
|
||||||
|
class FtraceCollector(CollectorBase):
|
||||||
|
|
||||||
|
# pylint: disable=too-many-locals,too-many-branches,too-many-statements
|
||||||
|
def __init__(self, target,
|
||||||
|
events=None,
|
||||||
|
functions=None,
|
||||||
|
tracer=None,
|
||||||
|
trace_children_functions=False,
|
||||||
|
buffer_size=None,
|
||||||
|
top_buffer_size=None,
|
||||||
|
buffer_size_step=1000,
|
||||||
|
tracing_path=None,
|
||||||
|
automark=True,
|
||||||
|
autoreport=True,
|
||||||
|
autoview=False,
|
||||||
|
no_install=False,
|
||||||
|
strict=False,
|
||||||
|
report_on_target=False,
|
||||||
|
trace_clock='local',
|
||||||
|
saved_cmdlines_nr=4096,
|
||||||
|
mode='write-to-memory',
|
||||||
|
):
|
||||||
|
super(FtraceCollector, self).__init__(target)
|
||||||
|
self.events = events if events is not None else DEFAULT_EVENTS
|
||||||
|
self.functions = functions
|
||||||
|
self.tracer = tracer
|
||||||
|
self.trace_children_functions = trace_children_functions
|
||||||
|
self.buffer_size = buffer_size
|
||||||
|
self.top_buffer_size = top_buffer_size
|
||||||
|
self.tracing_path = self._resolve_tracing_path(target, tracing_path)
|
||||||
|
self.automark = automark
|
||||||
|
self.autoreport = autoreport
|
||||||
|
self.autoview = autoview
|
||||||
|
self.strict = strict
|
||||||
|
self.report_on_target = report_on_target
|
||||||
|
self.target_output_file = target.path.join(self.target.working_directory, OUTPUT_TRACE_FILE)
|
||||||
|
text_file_name = target.path.splitext(OUTPUT_TRACE_FILE)[0] + '.txt'
|
||||||
|
self.target_text_file = target.path.join(self.target.working_directory, text_file_name)
|
||||||
|
self.output_path = None
|
||||||
|
self.target_binary = None
|
||||||
|
self.host_binary = None
|
||||||
|
self.start_time = None
|
||||||
|
self.stop_time = None
|
||||||
|
self.function_string = None
|
||||||
|
self.trace_clock = trace_clock
|
||||||
|
self.saved_cmdlines_nr = saved_cmdlines_nr
|
||||||
|
self._reset_needed = True
|
||||||
|
self.mode = mode
|
||||||
|
self._bg_cmd = None
|
||||||
|
|
||||||
|
# pylint: disable=bad-whitespace
|
||||||
|
# Setup tracing paths
|
||||||
|
self.available_events_file = self.target.path.join(self.tracing_path, 'available_events')
|
||||||
|
self.available_functions_file = self.target.path.join(self.tracing_path, 'available_filter_functions')
|
||||||
|
self.current_tracer_file = self.target.path.join(self.tracing_path, 'current_tracer')
|
||||||
|
self.function_profile_file = self.target.path.join(self.tracing_path, 'function_profile_enabled')
|
||||||
|
self.marker_file = self.target.path.join(self.tracing_path, 'trace_marker')
|
||||||
|
self.ftrace_filter_file = self.target.path.join(self.tracing_path, 'set_ftrace_filter')
|
||||||
|
self.available_tracers_file = self.target.path.join(self.tracing_path, 'available_tracers')
|
||||||
|
self.kprobe_events_file = self.target.path.join(self.tracing_path, 'kprobe_events')
|
||||||
|
|
||||||
|
self.host_binary = which('trace-cmd')
|
||||||
|
self.kernelshark = which('kernelshark')
|
||||||
|
|
||||||
|
if not self.target.is_rooted:
|
||||||
|
raise TargetStableError('trace-cmd instrument cannot be used on an unrooted device.')
|
||||||
|
if self.autoreport and not self.report_on_target and self.host_binary is None:
|
||||||
|
raise HostError('trace-cmd binary must be installed on the host if autoreport=True.')
|
||||||
|
if self.autoview and self.kernelshark is None:
|
||||||
|
raise HostError('kernelshark binary must be installed on the host if autoview=True.')
|
||||||
|
if not no_install:
|
||||||
|
host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi, 'trace-cmd')
|
||||||
|
self.target_binary = self.target.install(host_file)
|
||||||
|
else:
|
||||||
|
if not self.target.is_installed('trace-cmd'):
|
||||||
|
raise TargetStableError('No trace-cmd found on device and no_install=True is specified.')
|
||||||
|
self.target_binary = 'trace-cmd'
|
||||||
|
|
||||||
|
# Validate required events to be traced
|
||||||
|
def event_to_regex(event):
|
||||||
|
if not event.startswith('*'):
|
||||||
|
event = '*' + event
|
||||||
|
|
||||||
|
return re.compile(event.replace('*', '.*'))
|
||||||
|
|
||||||
|
def event_is_in_list(event, events):
|
||||||
|
return any(
|
||||||
|
event_to_regex(event).match(_event)
|
||||||
|
for _event in events
|
||||||
|
)
|
||||||
|
|
||||||
|
available_events = self.available_events
|
||||||
|
unavailable_events = [
|
||||||
|
event
|
||||||
|
for event in self.events
|
||||||
|
if not event_is_in_list(event, available_events)
|
||||||
|
]
|
||||||
|
if unavailable_events:
|
||||||
|
message = 'Events not available for tracing: {}'.format(
|
||||||
|
', '.join(unavailable_events)
|
||||||
|
)
|
||||||
|
if self.strict:
|
||||||
|
raise TargetStableError(message)
|
||||||
|
else:
|
||||||
|
self.target.logger.warning(message)
|
||||||
|
|
||||||
|
selected_events = sorted(set(self.events) - set(unavailable_events))
|
||||||
|
|
||||||
|
if self.tracer and self.tracer not in self.available_tracers:
|
||||||
|
raise TargetStableError('Unsupported tracer "{}". Available tracers: {}'.format(
|
||||||
|
self.tracer, ', '.join(self.available_tracers)))
|
||||||
|
|
||||||
|
# Check for function tracing support
|
||||||
|
if self.functions:
|
||||||
|
# Validate required functions to be traced
|
||||||
|
selected_functions = []
|
||||||
|
for function in self.functions:
|
||||||
|
if function not in self.available_functions:
|
||||||
|
message = 'Function [{}] not available for tracing/profiling'.format(function)
|
||||||
|
if self.strict:
|
||||||
|
raise TargetStableError(message)
|
||||||
|
self.target.logger.warning(message)
|
||||||
|
else:
|
||||||
|
selected_functions.append(function)
|
||||||
|
|
||||||
|
# Function profiling
|
||||||
|
if self.tracer is None:
|
||||||
|
if not self.target.file_exists(self.function_profile_file):
|
||||||
|
raise TargetStableError('Function profiling not supported. '\
|
||||||
|
'A kernel build with CONFIG_FUNCTION_PROFILER enable is required')
|
||||||
|
self.function_string = _build_trace_functions(selected_functions)
|
||||||
|
# If function profiling is enabled we always need at least one event.
|
||||||
|
# Thus, if not other events have been specified, try to add at least
|
||||||
|
# a tracepoint which is always available and possibly triggered few
|
||||||
|
# times.
|
||||||
|
if not selected_events:
|
||||||
|
selected_events = ['sched_wakeup_new']
|
||||||
|
|
||||||
|
# Function tracing
|
||||||
|
elif self.tracer == 'function':
|
||||||
|
self.function_string = _build_graph_functions(selected_functions, False)
|
||||||
|
|
||||||
|
# Function graphing
|
||||||
|
elif self.tracer == 'function_graph':
|
||||||
|
self.function_string = _build_graph_functions(selected_functions, trace_children_functions)
|
||||||
|
|
||||||
|
self._selected_events = selected_events
|
||||||
|
|
||||||
|
@property
|
||||||
|
def event_string(self):
|
||||||
|
return _build_trace_events(self._selected_events)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _resolve_tracing_path(cls, target, path):
|
||||||
|
if path is None:
|
||||||
|
return cls.find_tracing_path(target)
|
||||||
|
else:
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_tracing_path(cls, target):
|
||||||
|
fs_list = [
|
||||||
|
fs.mount_point
|
||||||
|
for fs in target.list_file_systems()
|
||||||
|
if fs.fs_type == 'tracefs'
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
return fs_list[0]
|
||||||
|
except IndexError:
|
||||||
|
# Default legacy value, when the kernel did not have a tracefs yet
|
||||||
|
return '/sys/kernel/debug/tracing'
|
||||||
|
|
||||||
|
@property
|
||||||
|
@memoized
|
||||||
|
def available_tracers(self):
|
||||||
|
"""
|
||||||
|
List of ftrace tracers supported by the target's kernel.
|
||||||
|
"""
|
||||||
|
return self.target.read_value(self.available_tracers_file).split(' ')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available_events(self):
|
||||||
|
"""
|
||||||
|
List of ftrace events supported by the target's kernel.
|
||||||
|
"""
|
||||||
|
return self.target.read_value(self.available_events_file).splitlines()
|
||||||
|
|
||||||
|
@property
|
||||||
|
@memoized
|
||||||
|
def available_functions(self):
|
||||||
|
"""
|
||||||
|
List of functions whose tracing/profiling is supported by the target's kernel.
|
||||||
|
"""
|
||||||
|
return self.target.read_value(self.available_functions_file).splitlines()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
# Save kprobe events
|
||||||
|
try:
|
||||||
|
kprobe_events = self.target.read_value(self.kprobe_events_file)
|
||||||
|
except TargetStableError:
|
||||||
|
kprobe_events = None
|
||||||
|
|
||||||
|
self.target.execute('{} reset -B devlib'.format(self.target_binary),
|
||||||
|
as_root=True, timeout=TIMEOUT)
|
||||||
|
|
||||||
|
# trace-cmd start will not set the top-level buffer size if passed -B
|
||||||
|
# parameter, but unfortunately some events still end up there (e.g.
|
||||||
|
# print event). So we still need to set that size, otherwise the buffer
|
||||||
|
# might be too small and some event lost.
|
||||||
|
top_buffer_size = self.top_buffer_size if self.top_buffer_size else self.buffer_size
|
||||||
|
if top_buffer_size:
|
||||||
|
self.target.write_value(
|
||||||
|
self.target.path.join(self.tracing_path, 'buffer_size_kb'),
|
||||||
|
top_buffer_size, verify=False
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.functions:
|
||||||
|
self.target.write_value(self.function_profile_file, 0, verify=False)
|
||||||
|
|
||||||
|
# Restore kprobe events
|
||||||
|
if kprobe_events:
|
||||||
|
self.target.write_value(self.kprobe_events_file, kprobe_events)
|
||||||
|
|
||||||
|
self._reset_needed = False
|
||||||
|
|
||||||
|
def _trace_frequencies(self):
|
||||||
|
if 'cpu_frequency' in self._selected_events:
|
||||||
|
self.logger.debug('Trace CPUFreq frequencies')
|
||||||
|
try:
|
||||||
|
mod = self.target.cpufreq
|
||||||
|
except TargetStableError as e:
|
||||||
|
self.logger.error(f'Could not trace CPUFreq frequencies as the cpufreq module cannot be loaded: {e}')
|
||||||
|
else:
|
||||||
|
mod.trace_frequencies()
|
||||||
|
|
||||||
|
def _trace_idle(self):
|
||||||
|
if 'cpu_idle' in self._selected_events:
|
||||||
|
self.logger.debug('Trace CPUIdle states')
|
||||||
|
try:
|
||||||
|
mod = self.target.cpuidle
|
||||||
|
except TargetStableError as e:
|
||||||
|
self.logger.error(f'Could not trace CPUIdle states as the cpuidle module cannot be loaded: {e}')
|
||||||
|
else:
|
||||||
|
mod.perturb_cpus()
|
||||||
|
|
||||||
|
@asyncf
|
||||||
|
async def start(self):
|
||||||
|
self.start_time = time.time()
|
||||||
|
if self._reset_needed:
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
if self.tracer is not None and 'function' in self.tracer:
|
||||||
|
tracecmd_functions = self.function_string
|
||||||
|
else:
|
||||||
|
tracecmd_functions = ''
|
||||||
|
|
||||||
|
tracer_string = '-p {}'.format(self.tracer) if self.tracer else ''
|
||||||
|
|
||||||
|
# Ensure kallsyms contains addresses if possible, so that function the
|
||||||
|
# collected trace contains enough data for pretty printing
|
||||||
|
with contextlib.suppress(TargetStableError):
|
||||||
|
self.target.write_value('/proc/sys/kernel/kptr_restrict', 0)
|
||||||
|
|
||||||
|
params = '-B devlib {buffer_size} {cmdlines_size} {clock} {events} {tracer} {functions}'.format(
|
||||||
|
events=self.event_string,
|
||||||
|
tracer=tracer_string,
|
||||||
|
functions=tracecmd_functions,
|
||||||
|
buffer_size='-b {}'.format(self.buffer_size) if self.buffer_size is not None else '',
|
||||||
|
clock='-C {}'.format(self.trace_clock) if self.trace_clock else '',
|
||||||
|
cmdlines_size='--cmdlines-size {}'.format(self.saved_cmdlines_nr) if self.saved_cmdlines_nr is not None else '',
|
||||||
|
)
|
||||||
|
|
||||||
|
mode = self.mode
|
||||||
|
if mode == 'write-to-disk':
|
||||||
|
bg_cmd = self.target.background(
|
||||||
|
# cd into the working_directory first to workaround this issue:
|
||||||
|
# https://lore.kernel.org/linux-trace-devel/20240119162743.1a107fa9@gandalf.local.home/
|
||||||
|
f'cd {self.target.working_directory} && devlib-signal-target {self.target_binary} record -o {quote(self.target_output_file)} {params}',
|
||||||
|
as_root=True,
|
||||||
|
)
|
||||||
|
assert self._bg_cmd is None
|
||||||
|
self._bg_cmd = bg_cmd.__enter__()
|
||||||
|
elif mode == 'write-to-memory':
|
||||||
|
self.target.execute(
|
||||||
|
f'{self.target_binary} start {params}',
|
||||||
|
as_root=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown mode {mode}')
|
||||||
|
|
||||||
|
if self.automark:
|
||||||
|
self.mark_start()
|
||||||
|
|
||||||
|
self._trace_frequencies()
|
||||||
|
self._trace_idle()
|
||||||
|
|
||||||
|
# Enable kernel function profiling
|
||||||
|
if self.functions and self.tracer is None:
|
||||||
|
target = self.target
|
||||||
|
await target.async_manager.concurrently(
|
||||||
|
execute.asyn('echo nop > {}'.format(self.current_tracer_file),
|
||||||
|
as_root=True),
|
||||||
|
execute.asyn('echo 0 > {}'.format(self.function_profile_file),
|
||||||
|
as_root=True),
|
||||||
|
execute.asyn('echo {} > {}'.format(self.function_string, self.ftrace_filter_file),
|
||||||
|
as_root=True),
|
||||||
|
execute.asyn('echo 1 > {}'.format(self.function_profile_file),
|
||||||
|
as_root=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
# Disable kernel function profiling
|
||||||
|
if self.functions and self.tracer is None:
|
||||||
|
self.target.execute('echo 0 > {}'.format(self.function_profile_file),
|
||||||
|
as_root=True)
|
||||||
|
self.stop_time = time.time()
|
||||||
|
if self.automark:
|
||||||
|
self.mark_stop()
|
||||||
|
|
||||||
|
mode = self.mode
|
||||||
|
if mode == 'write-to-disk':
|
||||||
|
bg_cmd = self._bg_cmd
|
||||||
|
self._bg_cmd = None
|
||||||
|
assert bg_cmd is not None
|
||||||
|
bg_cmd.send_signal(signal.SIGINT)
|
||||||
|
bg_cmd.communicate()
|
||||||
|
bg_cmd.__exit__(None, None, None)
|
||||||
|
elif mode == 'write-to-memory':
|
||||||
|
self.target.execute('{} stop -B devlib'.format(self.target_binary),
|
||||||
|
timeout=TIMEOUT, as_root=True)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown mode {mode}')
|
||||||
|
|
||||||
|
self._reset_needed = True
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
|
if os.path.isdir(output_path):
|
||||||
|
output_path = os.path.join(output_path, os.path.basename(self.target_output_file))
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
|
||||||
|
busybox = quote(self.target.busybox)
|
||||||
|
|
||||||
|
mode = self.mode
|
||||||
|
if mode == 'write-to-disk':
|
||||||
|
# Interrupting trace-cmd record will make it create the file
|
||||||
|
pass
|
||||||
|
elif mode == 'write-to-memory':
|
||||||
|
cmd = f'{self.target_binary} extract -B devlib -o {self.target_output_file} && {busybox} chmod 666 {self.target_output_file}'
|
||||||
|
self.target.execute(cmd, timeout=TIMEOUT, as_root=True)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown mode {mode}')
|
||||||
|
|
||||||
|
# The size of trace.dat will depend on how long trace-cmd was running.
|
||||||
|
# Therefore timout for the pull command must also be adjusted
|
||||||
|
# accordingly.
|
||||||
|
pull_timeout = 10 * (self.stop_time - self.start_time)
|
||||||
|
self.target.pull(self.target_output_file, self.output_path, timeout=pull_timeout)
|
||||||
|
output = CollectorOutput()
|
||||||
|
if not os.path.isfile(self.output_path):
|
||||||
|
self.logger.warning('Binary trace not pulled from device.')
|
||||||
|
else:
|
||||||
|
output.append(CollectorOutputEntry(self.output_path, 'file'))
|
||||||
|
if self.autoreport:
|
||||||
|
textfile = os.path.splitext(self.output_path)[0] + '.txt'
|
||||||
|
if self.report_on_target:
|
||||||
|
self.generate_report_on_target()
|
||||||
|
self.target.pull(self.target_text_file,
|
||||||
|
textfile, timeout=pull_timeout)
|
||||||
|
else:
|
||||||
|
self.report(self.output_path, textfile)
|
||||||
|
output.append(CollectorOutputEntry(textfile, 'file'))
|
||||||
|
if self.autoview:
|
||||||
|
self.view(self.output_path)
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_stats(self, outfile):
|
||||||
|
if not (self.functions and self.tracer is None):
|
||||||
|
return
|
||||||
|
|
||||||
|
if os.path.isdir(outfile):
|
||||||
|
outfile = os.path.join(outfile, OUTPUT_PROFILE_FILE)
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
output = self.target._execute_util('ftrace_get_function_stats',
|
||||||
|
as_root=True)
|
||||||
|
|
||||||
|
function_stats = {}
|
||||||
|
for line in output.splitlines():
|
||||||
|
# Match a new CPU dataset
|
||||||
|
match = CPU_RE.search(line)
|
||||||
|
if match:
|
||||||
|
cpu_id = int(match.group(1))
|
||||||
|
function_stats[cpu_id] = {}
|
||||||
|
self.logger.debug("Processing stats for CPU%d...", cpu_id)
|
||||||
|
continue
|
||||||
|
# Match a new function dataset
|
||||||
|
match = STATS_RE.search(line)
|
||||||
|
if match:
|
||||||
|
fname = match.group(1)
|
||||||
|
function_stats[cpu_id][fname] = {
|
||||||
|
'hits' : int(match.group(2)),
|
||||||
|
'time' : float(match.group(3)),
|
||||||
|
'avg' : float(match.group(4)),
|
||||||
|
's_2' : float(match.group(5)),
|
||||||
|
}
|
||||||
|
self.logger.debug(" %s: %s",
|
||||||
|
fname, function_stats[cpu_id][fname])
|
||||||
|
|
||||||
|
self.logger.debug("FTrace stats output [%s]...", outfile)
|
||||||
|
with open(outfile, 'w') as fh:
|
||||||
|
json.dump(function_stats, fh, indent=4)
|
||||||
|
self.logger.debug("FTrace function stats save in [%s]", outfile)
|
||||||
|
|
||||||
|
return function_stats
|
||||||
|
|
||||||
|
def report(self, binfile, destfile):
|
||||||
|
# To get the output of trace.dat, trace-cmd must be installed
|
||||||
|
# This is done host-side because the generated file is very large
|
||||||
|
try:
|
||||||
|
command = '{} report {} > {}'.format(self.host_binary, binfile, destfile)
|
||||||
|
self.logger.debug(command)
|
||||||
|
process = subprocess.Popen(command, stderr=subprocess.PIPE, shell=True)
|
||||||
|
_, error = process.communicate()
|
||||||
|
error = error.decode(sys.stdout.encoding or 'utf-8', 'replace')
|
||||||
|
if process.returncode:
|
||||||
|
raise TargetStableError('trace-cmd returned non-zero exit code {}'.format(process.returncode))
|
||||||
|
if error:
|
||||||
|
# logged at debug level, as trace-cmd always outputs some
|
||||||
|
# errors that seem benign.
|
||||||
|
self.logger.debug(error)
|
||||||
|
if os.path.isfile(destfile):
|
||||||
|
self.logger.debug('Verifying traces.')
|
||||||
|
with open(destfile) as fh:
|
||||||
|
for line in fh:
|
||||||
|
if 'EVENTS DROPPED' in line:
|
||||||
|
self.logger.warning('Dropped events detected.')
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.logger.debug('Trace verified.')
|
||||||
|
else:
|
||||||
|
self.logger.warning('Could not generate trace.txt.')
|
||||||
|
except OSError:
|
||||||
|
raise HostError('Could not find trace-cmd. Please make sure it is installed and is in PATH.')
|
||||||
|
|
||||||
|
def generate_report_on_target(self):
|
||||||
|
command = '{} report {} > {}'.format(self.target_binary,
|
||||||
|
self.target_output_file,
|
||||||
|
self.target_text_file)
|
||||||
|
self.target.execute(command, timeout=TIMEOUT)
|
||||||
|
|
||||||
|
def view(self, binfile):
|
||||||
|
check_output('{} {}'.format(self.kernelshark, binfile), shell=True)
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
self.target.remove(self.target.path.join(self.target.working_directory, OUTPUT_TRACE_FILE))
|
||||||
|
|
||||||
|
def mark_start(self):
|
||||||
|
self.target.write_value(self.marker_file, TRACE_MARKER_START, verify=False)
|
||||||
|
|
||||||
|
def mark_stop(self):
|
||||||
|
self.target.write_value(self.marker_file, TRACE_MARKER_STOP, verify=False)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_trace_events(events):
|
||||||
|
event_string = ' '.join(['-e {}'.format(e) for e in events])
|
||||||
|
return event_string
|
||||||
|
|
||||||
|
def _build_trace_functions(functions):
|
||||||
|
function_string = " ".join(functions)
|
||||||
|
return function_string
|
||||||
|
|
||||||
|
def _build_graph_functions(functions, trace_children_functions):
|
||||||
|
opt = 'g' if trace_children_functions else 'l'
|
||||||
|
return ' '.join(
|
||||||
|
'-{} {}'.format(opt, quote(f))
|
||||||
|
for f in functions
|
||||||
|
)
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018 ARM Limited
|
# Copyright 2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -14,19 +14,21 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
from devlib.trace import TraceCollector
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
from devlib.utils.android import LogcatMonitor
|
from devlib.utils.android import LogcatMonitor
|
||||||
|
|
||||||
class LogcatCollector(TraceCollector):
|
class LogcatCollector(CollectorBase):
|
||||||
|
|
||||||
def __init__(self, target, regexps=None):
|
def __init__(self, target, regexps=None, logcat_format=None):
|
||||||
super(LogcatCollector, self).__init__(target)
|
super(LogcatCollector, self).__init__(target)
|
||||||
self.regexps = regexps
|
self.regexps = regexps
|
||||||
|
self.logcat_format = logcat_format
|
||||||
|
self.output_path = None
|
||||||
self._collecting = False
|
self._collecting = False
|
||||||
self._prev_log = None
|
self._prev_log = None
|
||||||
|
self._monitor = None
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
@ -45,12 +47,14 @@ class LogcatCollector(TraceCollector):
|
|||||||
"""
|
"""
|
||||||
Start collecting logcat lines
|
Start collecting logcat lines
|
||||||
"""
|
"""
|
||||||
self._monitor = LogcatMonitor(self.target, self.regexps)
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
self._monitor = LogcatMonitor(self.target, self.regexps, logcat_format=self.logcat_format)
|
||||||
if self._prev_log:
|
if self._prev_log:
|
||||||
# Append new data collection to previous collection
|
# Append new data collection to previous collection
|
||||||
self._monitor.start(self._prev_log)
|
self._monitor.start(self._prev_log)
|
||||||
else:
|
else:
|
||||||
self._monitor.start()
|
self._monitor.start(self.output_path)
|
||||||
|
|
||||||
self._collecting = True
|
self._collecting = True
|
||||||
|
|
||||||
@ -65,9 +69,10 @@ class LogcatCollector(TraceCollector):
|
|||||||
self._collecting = False
|
self._collecting = False
|
||||||
self._prev_log = self._monitor.logfile
|
self._prev_log = self._monitor.logfile
|
||||||
|
|
||||||
def get_trace(self, outfile):
|
def set_output(self, output_path):
|
||||||
"""
|
self.output_path = output_path
|
||||||
Output collected logcat lines to designated file
|
|
||||||
"""
|
def get_data(self):
|
||||||
# copy self._monitor.logfile to outfile
|
if self.output_path is None:
|
||||||
shutil.copy(self._monitor.logfile, outfile)
|
raise RuntimeError("No data collected.")
|
||||||
|
return CollectorOutput([CollectorOutputEntry(self.output_path, 'file')])
|
283
devlib/collector/perf.py
Normal file
283
devlib/collector/perf.py
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
# Copyright 2018 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
from past.builtins import basestring, zip
|
||||||
|
|
||||||
|
from devlib.host import PACKAGE_BIN_DIRECTORY
|
||||||
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
|
from devlib.utils.misc import ensure_file_directory_exists as _f
|
||||||
|
|
||||||
|
|
||||||
|
PERF_STAT_COMMAND_TEMPLATE = '{binary} {command} {options} {events} {sleep_cmd} > {outfile} 2>&1 '
|
||||||
|
PERF_REPORT_COMMAND_TEMPLATE= '{binary} report {options} -i {datafile} > {outfile} 2>&1 '
|
||||||
|
PERF_REPORT_SAMPLE_COMMAND_TEMPLATE= '{binary} report-sample {options} -i {datafile} > {outfile} '
|
||||||
|
PERF_RECORD_COMMAND_TEMPLATE= '{binary} record {options} {events} -o {outfile}'
|
||||||
|
|
||||||
|
PERF_DEFAULT_EVENTS = [
|
||||||
|
'cpu-migrations',
|
||||||
|
'context-switches',
|
||||||
|
]
|
||||||
|
|
||||||
|
SIMPLEPERF_DEFAULT_EVENTS = [
|
||||||
|
'raw-cpu-cycles',
|
||||||
|
'raw-l1-dcache',
|
||||||
|
'raw-l1-dcache-refill',
|
||||||
|
'raw-br-mis-pred',
|
||||||
|
'raw-instruction-retired',
|
||||||
|
]
|
||||||
|
|
||||||
|
DEFAULT_EVENTS = {'perf':PERF_DEFAULT_EVENTS, 'simpleperf':SIMPLEPERF_DEFAULT_EVENTS}
|
||||||
|
|
||||||
|
class PerfCollector(CollectorBase):
|
||||||
|
"""
|
||||||
|
Perf is a Linux profiling with performance counters.
|
||||||
|
Simpleperf is an Android profiling tool with performance counters.
|
||||||
|
|
||||||
|
It is highly recomended to use perf_type = simpleperf when using this instrument
|
||||||
|
on android devices, since it recognises android symbols in record mode and is much more stable
|
||||||
|
when reporting record .data files. For more information see simpleperf documentation at:
|
||||||
|
https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/README.md
|
||||||
|
|
||||||
|
Performance counters are CPU hardware registers that count hardware events
|
||||||
|
such as instructions executed, cache-misses suffered, or branches
|
||||||
|
mispredicted. They form a basis for profiling applications to trace dynamic
|
||||||
|
control flow and identify hotspots.
|
||||||
|
|
||||||
|
Perf accepts options and events. If no option is given the default '-a' is
|
||||||
|
used. For events, the default events are migrations and cs for perf and raw-cpu-cycles,
|
||||||
|
raw-l1-dcache, raw-l1-dcache-refill, raw-instructions-retired. They both can
|
||||||
|
be specified in the config file.
|
||||||
|
|
||||||
|
Events must be provided as a list that contains them and they will look like
|
||||||
|
this ::
|
||||||
|
|
||||||
|
perf_events = ['migrations', 'cs']
|
||||||
|
|
||||||
|
Events can be obtained by typing the following in the command line on the
|
||||||
|
device ::
|
||||||
|
|
||||||
|
perf list
|
||||||
|
simpleperf list
|
||||||
|
|
||||||
|
Whereas options, they can be provided as a single string as following ::
|
||||||
|
|
||||||
|
perf_options = '-a -i'
|
||||||
|
|
||||||
|
Options can be obtained by running the following in the command line ::
|
||||||
|
|
||||||
|
man perf-stat
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
target,
|
||||||
|
perf_type='perf',
|
||||||
|
command='stat',
|
||||||
|
events=None,
|
||||||
|
optionstring=None,
|
||||||
|
report_options=None,
|
||||||
|
run_report_sample=False,
|
||||||
|
report_sample_options=None,
|
||||||
|
labels=None,
|
||||||
|
force_install=False,
|
||||||
|
validate_events=True):
|
||||||
|
super(PerfCollector, self).__init__(target)
|
||||||
|
self.force_install = force_install
|
||||||
|
self.labels = labels
|
||||||
|
self.report_options = report_options
|
||||||
|
self.run_report_sample = run_report_sample
|
||||||
|
self.report_sample_options = report_sample_options
|
||||||
|
self.output_path = None
|
||||||
|
self.validate_events = validate_events
|
||||||
|
|
||||||
|
# Validate parameters
|
||||||
|
if isinstance(optionstring, list):
|
||||||
|
self.optionstrings = optionstring
|
||||||
|
else:
|
||||||
|
self.optionstrings = [optionstring]
|
||||||
|
if perf_type in ['perf', 'simpleperf']:
|
||||||
|
self.perf_type = perf_type
|
||||||
|
else:
|
||||||
|
raise ValueError('Invalid perf type: {}, must be perf or simpleperf'.format(perf_type))
|
||||||
|
if not events:
|
||||||
|
self.events = DEFAULT_EVENTS[self.perf_type]
|
||||||
|
else:
|
||||||
|
self.events = events
|
||||||
|
if isinstance(self.events, basestring):
|
||||||
|
self.events = [self.events]
|
||||||
|
if not self.labels:
|
||||||
|
self.labels = ['perf_{}'.format(i) for i in range(len(self.optionstrings))]
|
||||||
|
if len(self.labels) != len(self.optionstrings):
|
||||||
|
raise ValueError('The number of labels must match the number of optstrings provided for perf.')
|
||||||
|
if command in ['stat', 'record']:
|
||||||
|
self.command = command
|
||||||
|
else:
|
||||||
|
raise ValueError('Unsupported perf command, must be stat or record')
|
||||||
|
if report_options and (command != 'record'):
|
||||||
|
raise ValueError('report_options specified, but command is not record')
|
||||||
|
if report_sample_options and (command != 'record'):
|
||||||
|
raise ValueError('report_sample_options specified, but command is not record')
|
||||||
|
|
||||||
|
self.binary = self.target.get_installed(self.perf_type)
|
||||||
|
if self.force_install or not self.binary:
|
||||||
|
self.binary = self._deploy_perf()
|
||||||
|
|
||||||
|
if self.validate_events:
|
||||||
|
self._validate_events(self.events)
|
||||||
|
|
||||||
|
self.commands = self._build_commands()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.target.killall(self.perf_type, as_root=self.target.is_rooted)
|
||||||
|
self.target.remove(self.target.get_workpath('TemporaryFile*'))
|
||||||
|
for label in self.labels:
|
||||||
|
filepath = self._get_target_file(label, 'data')
|
||||||
|
self.target.remove(filepath)
|
||||||
|
filepath = self._get_target_file(label, 'rpt')
|
||||||
|
self.target.remove(filepath)
|
||||||
|
filepath = self._get_target_file(label, 'rptsamples')
|
||||||
|
self.target.remove(filepath)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
for command in self.commands:
|
||||||
|
self.target.background(command, as_root=self.target.is_rooted)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.target.killall(self.perf_type, signal='SIGINT',
|
||||||
|
as_root=self.target.is_rooted)
|
||||||
|
if self.perf_type == "perf" and self.command == "stat":
|
||||||
|
# perf doesn't transmit the signal to its sleep call so handled here:
|
||||||
|
self.target.killall('sleep', as_root=self.target.is_rooted)
|
||||||
|
# NB: we hope that no other "important" sleep is on-going
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
|
||||||
|
output = CollectorOutput()
|
||||||
|
|
||||||
|
for label in self.labels:
|
||||||
|
if self.command == 'record':
|
||||||
|
self._wait_for_data_file_write(label, self.output_path)
|
||||||
|
path = self._pull_target_file_to_host(label, 'rpt', self.output_path)
|
||||||
|
output.append(CollectorOutputEntry(path, 'file'))
|
||||||
|
if self.run_report_sample:
|
||||||
|
report_samples_path = self._pull_target_file_to_host(label, 'rptsamples', self.output_path)
|
||||||
|
output.append(CollectorOutputEntry(report_samples_path, 'file'))
|
||||||
|
else:
|
||||||
|
path = self._pull_target_file_to_host(label, 'out', self.output_path)
|
||||||
|
output.append(CollectorOutputEntry(path, 'file'))
|
||||||
|
return output
|
||||||
|
|
||||||
|
def _deploy_perf(self):
|
||||||
|
host_executable = os.path.join(PACKAGE_BIN_DIRECTORY,
|
||||||
|
self.target.abi, self.perf_type)
|
||||||
|
return self.target.install(host_executable)
|
||||||
|
|
||||||
|
def _get_target_file(self, label, extension):
|
||||||
|
return self.target.get_workpath('{}.{}'.format(label, extension))
|
||||||
|
|
||||||
|
def _build_commands(self):
|
||||||
|
commands = []
|
||||||
|
for opts, label in zip(self.optionstrings, self.labels):
|
||||||
|
if self.command == 'stat':
|
||||||
|
commands.append(self._build_perf_stat_command(opts, self.events, label))
|
||||||
|
else:
|
||||||
|
commands.append(self._build_perf_record_command(opts, label))
|
||||||
|
return commands
|
||||||
|
|
||||||
|
def _build_perf_stat_command(self, options, events, label):
|
||||||
|
event_string = ' '.join(['-e {}'.format(e) for e in events])
|
||||||
|
sleep_cmd = 'sleep 1000' if self.perf_type == 'perf' else ''
|
||||||
|
command = PERF_STAT_COMMAND_TEMPLATE.format(binary = self.binary,
|
||||||
|
command = self.command,
|
||||||
|
options = options or '',
|
||||||
|
events = event_string,
|
||||||
|
sleep_cmd = sleep_cmd,
|
||||||
|
outfile = self._get_target_file(label, 'out'))
|
||||||
|
return command
|
||||||
|
|
||||||
|
def _build_perf_report_command(self, report_options, label):
|
||||||
|
command = PERF_REPORT_COMMAND_TEMPLATE.format(binary=self.binary,
|
||||||
|
options=report_options or '',
|
||||||
|
datafile=self._get_target_file(label, 'data'),
|
||||||
|
outfile=self._get_target_file(label, 'rpt'))
|
||||||
|
return command
|
||||||
|
|
||||||
|
def _build_perf_report_sample_command(self, label):
|
||||||
|
command = PERF_REPORT_SAMPLE_COMMAND_TEMPLATE.format(binary=self.binary,
|
||||||
|
options=self.report_sample_options or '',
|
||||||
|
datafile=self._get_target_file(label, 'data'),
|
||||||
|
outfile=self._get_target_file(label, 'rptsamples'))
|
||||||
|
return command
|
||||||
|
|
||||||
|
def _build_perf_record_command(self, options, label):
|
||||||
|
event_string = ' '.join(['-e {}'.format(e) for e in self.events])
|
||||||
|
command = PERF_RECORD_COMMAND_TEMPLATE.format(binary=self.binary,
|
||||||
|
options=options or '',
|
||||||
|
events=event_string,
|
||||||
|
outfile=self._get_target_file(label, 'data'))
|
||||||
|
return command
|
||||||
|
|
||||||
|
def _pull_target_file_to_host(self, label, extension, output_path):
|
||||||
|
target_file = self._get_target_file(label, extension)
|
||||||
|
host_relpath = os.path.basename(target_file)
|
||||||
|
host_file = _f(os.path.join(output_path, host_relpath))
|
||||||
|
self.target.pull(target_file, host_file)
|
||||||
|
return host_file
|
||||||
|
|
||||||
|
def _wait_for_data_file_write(self, label, output_path):
|
||||||
|
data_file_finished_writing = False
|
||||||
|
max_tries = 80
|
||||||
|
current_tries = 0
|
||||||
|
while not data_file_finished_writing:
|
||||||
|
files = self.target.execute('cd {} && ls'.format(self.target.get_workpath('')))
|
||||||
|
# Perf stores data in tempory files whilst writing to data output file. Check if they have been removed.
|
||||||
|
if 'TemporaryFile' in files and current_tries <= max_tries:
|
||||||
|
time.sleep(0.25)
|
||||||
|
current_tries += 1
|
||||||
|
else:
|
||||||
|
if current_tries >= max_tries:
|
||||||
|
self.logger.warning('''writing {}.data file took longer than expected,
|
||||||
|
file may not have written correctly'''.format(label))
|
||||||
|
data_file_finished_writing = True
|
||||||
|
report_command = self._build_perf_report_command(self.report_options, label)
|
||||||
|
self.target.execute(report_command)
|
||||||
|
if self.run_report_sample:
|
||||||
|
report_sample_command = self._build_perf_report_sample_command(label)
|
||||||
|
self.target.execute(report_sample_command)
|
||||||
|
|
||||||
|
def _validate_events(self, events):
|
||||||
|
available_events_string = self.target.execute('{} list | {} cat'.format(self.perf_type, self.target.busybox))
|
||||||
|
available_events = available_events_string.splitlines()
|
||||||
|
for available_event in available_events:
|
||||||
|
if available_event == '':
|
||||||
|
continue
|
||||||
|
if 'OR' in available_event:
|
||||||
|
available_events.append(available_event.split('OR')[1])
|
||||||
|
available_events[available_events.index(available_event)] = available_event.split()[0].strip()
|
||||||
|
# Raw hex event codes can also be passed in that do not appear on perf/simpleperf list, prefixed with 'r'
|
||||||
|
raw_event_code_regex = re.compile(r"^r(0x|0X)?[A-Fa-f0-9]+$")
|
||||||
|
for event in events:
|
||||||
|
if event in available_events or re.match(raw_event_code_regex, event):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
raise ValueError('Event: {} is not in available event list for {}'.format(event, self.perf_type))
|
119
devlib/collector/perfetto.py
Normal file
119
devlib/collector/perfetto.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# Copyright 2023 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from shlex import quote
|
||||||
|
|
||||||
|
from devlib.host import PACKAGE_BIN_DIRECTORY
|
||||||
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
|
from devlib.exception import TargetStableError, HostError
|
||||||
|
|
||||||
|
OUTPUT_PERFETTO_TRACE = 'devlib-trace.perfetto-trace'
|
||||||
|
|
||||||
|
|
||||||
|
class PerfettoCollector(CollectorBase):
|
||||||
|
"""
|
||||||
|
Perfetto is a production-grade open-source stack for performance instrumentation
|
||||||
|
and trace analysis developed by Google. It offers services and libraries for
|
||||||
|
recording system-level and app-level traces, native + java heap profiling,
|
||||||
|
a library for analyzing traces using SQL and a web-based UI to visualize and
|
||||||
|
explore multi-GB traces.
|
||||||
|
|
||||||
|
This collector takes a path to a perfetto config file saved on disk and passes
|
||||||
|
it directly to the tool.
|
||||||
|
|
||||||
|
On Android platfroms Perfetto is included in the framework starting with Android 9.
|
||||||
|
On Android 8 and below, follow the Linux instructions below to build and include
|
||||||
|
the standalone tracebox binary.
|
||||||
|
|
||||||
|
On Linux platforms, either traced (Perfetto tracing daemon) needs to be running
|
||||||
|
in the background or the tracebox binary needs to be built from source and placed
|
||||||
|
in the Package Bin directory. The build instructions can be found here:
|
||||||
|
|
||||||
|
It is also possible to force using the prebuilt tracebox binary on platforms which
|
||||||
|
already have traced running using the force_tracebox collector parameter.
|
||||||
|
|
||||||
|
https://perfetto.dev/docs/contributing/build-instructions
|
||||||
|
|
||||||
|
After building the 'tracebox' binary should be copied to devlib/bin/<arch>/.
|
||||||
|
|
||||||
|
For more information consult the official documentation:
|
||||||
|
https://perfetto.dev/docs/
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, target, config=None, force_tracebox=False):
|
||||||
|
super().__init__(target)
|
||||||
|
self.bg_cmd = None
|
||||||
|
self.config = config
|
||||||
|
self.target_binary = 'perfetto'
|
||||||
|
target_output_path = self.target.working_directory
|
||||||
|
|
||||||
|
install_tracebox = force_tracebox or (target.os in ['linux', 'android'] and not target.is_running('traced'))
|
||||||
|
|
||||||
|
# Install Perfetto through tracebox
|
||||||
|
if install_tracebox:
|
||||||
|
self.target_binary = 'tracebox'
|
||||||
|
if not self.target.get_installed(self.target_binary):
|
||||||
|
host_executable = os.path.join(PACKAGE_BIN_DIRECTORY,
|
||||||
|
self.target.abi, self.target_binary)
|
||||||
|
if not os.path.exists(host_executable):
|
||||||
|
raise HostError("{} not found on the host".format(self.target_binary))
|
||||||
|
self.target.install(host_executable)
|
||||||
|
# Use Android's built-in Perfetto
|
||||||
|
elif target.os == 'android':
|
||||||
|
os_version = target.os_version['release']
|
||||||
|
if int(os_version) >= 9:
|
||||||
|
# Android requires built-in Perfetto to write to this directory
|
||||||
|
target_output_path = '/data/misc/perfetto-traces'
|
||||||
|
# Android 9 and 10 require traced to be enabled manually
|
||||||
|
if int(os_version) <= 10:
|
||||||
|
target.execute('setprop persist.traced.enable 1')
|
||||||
|
|
||||||
|
self.target_output_file = target.path.join(target_output_path, OUTPUT_PERFETTO_TRACE)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
cmd = "{} cat {} | {} --txt -c - -o {}".format(
|
||||||
|
quote(self.target.busybox), quote(self.config), quote(self.target_binary), quote(self.target_output_file)
|
||||||
|
)
|
||||||
|
# start tracing
|
||||||
|
if self.bg_cmd is None:
|
||||||
|
self.bg_cmd = self.target.background(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
else:
|
||||||
|
raise TargetStableError('Perfetto collector is not re-entrant')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
# stop tracing
|
||||||
|
self.bg_cmd.cancel()
|
||||||
|
self.bg_cmd = None
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
|
if os.path.isdir(output_path):
|
||||||
|
output_path = os.path.join(output_path, os.path.basename(self.target_output_file))
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
if not self.target.file_exists(self.target_output_file):
|
||||||
|
raise RuntimeError("Output file not found on the device")
|
||||||
|
self.target.pull(self.target_output_file, self.output_path)
|
||||||
|
output = CollectorOutput()
|
||||||
|
if not os.path.isfile(self.output_path):
|
||||||
|
self.logger.warning('Perfetto trace not pulled from device.')
|
||||||
|
else:
|
||||||
|
output.append(CollectorOutputEntry(self.output_path, 'file'))
|
||||||
|
return output
|
@ -19,13 +19,14 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from devlib.trace import TraceCollector
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
from devlib.exception import WorkerThreadError
|
from devlib.exception import WorkerThreadError
|
||||||
|
|
||||||
|
|
||||||
class ScreenCapturePoller(threading.Thread):
|
class ScreenCapturePoller(threading.Thread):
|
||||||
|
|
||||||
def __init__(self, target, period, output_path=None, timeout=30):
|
def __init__(self, target, period, timeout=30):
|
||||||
super(ScreenCapturePoller, self).__init__()
|
super(ScreenCapturePoller, self).__init__()
|
||||||
self.target = target
|
self.target = target
|
||||||
self.logger = logging.getLogger('screencapture')
|
self.logger = logging.getLogger('screencapture')
|
||||||
@ -36,11 +37,16 @@ class ScreenCapturePoller(threading.Thread):
|
|||||||
self.last_poll = 0
|
self.last_poll = 0
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
self.exc = None
|
self.exc = None
|
||||||
|
self.output_path = None
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
self.output_path = output_path
|
self.output_path = output_path
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.logger.debug('Starting screen capture polling')
|
self.logger.debug('Starting screen capture polling')
|
||||||
try:
|
try:
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
while True:
|
while True:
|
||||||
if self.stop_signal.is_set():
|
if self.stop_signal.is_set():
|
||||||
break
|
break
|
||||||
@ -66,24 +72,33 @@ class ScreenCapturePoller(threading.Thread):
|
|||||||
self.target.capture_screen(os.path.join(self.output_path, "screencap_{ts}.png"))
|
self.target.capture_screen(os.path.join(self.output_path, "screencap_{ts}.png"))
|
||||||
|
|
||||||
|
|
||||||
class ScreenCaptureCollector(TraceCollector):
|
class ScreenCaptureCollector(CollectorBase):
|
||||||
|
|
||||||
def __init__(self, target, output_path=None, period=None):
|
def __init__(self, target, period=None):
|
||||||
super(ScreenCaptureCollector, self).__init__(target)
|
super(ScreenCaptureCollector, self).__init__(target)
|
||||||
self._collecting = False
|
self._collecting = False
|
||||||
self.output_path = output_path
|
self.output_path = None
|
||||||
self.period = period
|
self.period = period
|
||||||
self.target = target
|
self.target = target
|
||||||
self._poller = ScreenCapturePoller(self.target, self.period,
|
|
||||||
self.output_path)
|
def set_output(self, output_path):
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
pass
|
self._poller = ScreenCapturePoller(self.target, self.period)
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("No data collected.")
|
||||||
|
return CollectorOutput([CollectorOutputEntry(self.output_path, 'directory')])
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""
|
"""
|
||||||
Start collecting the screenshots
|
Start collecting the screenshots
|
||||||
"""
|
"""
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
self._poller.set_output(self.output_path)
|
||||||
self._poller.start()
|
self._poller.start()
|
||||||
self._collecting = True
|
self._collecting = True
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018 ARM Limited
|
# Copyright 2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -14,14 +14,13 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
from pexpect.exceptions import TIMEOUT
|
from pexpect.exceptions import TIMEOUT
|
||||||
import shutil
|
|
||||||
from tempfile import NamedTemporaryFile
|
|
||||||
|
|
||||||
from devlib.trace import TraceCollector
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
|
CollectorOutputEntry)
|
||||||
from devlib.utils.serial_port import get_connection
|
from devlib.utils.serial_port import get_connection
|
||||||
|
|
||||||
|
|
||||||
class SerialTraceCollector(TraceCollector):
|
class SerialTraceCollector(CollectorBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def collecting(self):
|
def collecting(self):
|
||||||
@ -32,32 +31,35 @@ class SerialTraceCollector(TraceCollector):
|
|||||||
self.serial_port = serial_port
|
self.serial_port = serial_port
|
||||||
self.baudrate = baudrate
|
self.baudrate = baudrate
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
self.output_path = None
|
||||||
|
|
||||||
self._serial_target = None
|
self._serial_target = None
|
||||||
self._conn = None
|
self._conn = None
|
||||||
self._tmpfile = None
|
self._outfile_fh = None
|
||||||
self._collecting = False
|
self._collecting = False
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
if self._collecting:
|
if self._collecting:
|
||||||
raise RuntimeError("reset was called whilst collecting")
|
raise RuntimeError("reset was called whilst collecting")
|
||||||
|
|
||||||
if self._tmpfile:
|
if self._outfile_fh:
|
||||||
self._tmpfile.close()
|
self._outfile_fh.close()
|
||||||
self._tmpfile = None
|
self._outfile_fh = None
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self._collecting:
|
if self._collecting:
|
||||||
raise RuntimeError("start was called whilst collecting")
|
raise RuntimeError("start was called whilst collecting")
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
|
||||||
|
self._outfile_fh = open(self.output_path, 'wb')
|
||||||
self._tmpfile = NamedTemporaryFile()
|
start_marker = "-------- Starting serial logging --------\n"
|
||||||
self._tmpfile.write("-------- Starting serial logging --------\n")
|
self._outfile_fh.write(start_marker.encode('utf-8'))
|
||||||
|
|
||||||
self._serial_target, self._conn = get_connection(port=self.serial_port,
|
self._serial_target, self._conn = get_connection(port=self.serial_port,
|
||||||
baudrate=self.baudrate,
|
baudrate=self.baudrate,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
logfile=self._tmpfile,
|
logfile=self._outfile_fh,
|
||||||
init_dtr=0)
|
init_dtr=0)
|
||||||
self._collecting = True
|
self._collecting = True
|
||||||
|
|
||||||
@ -76,17 +78,20 @@ class SerialTraceCollector(TraceCollector):
|
|||||||
self._serial_target.close()
|
self._serial_target.close()
|
||||||
del self._conn
|
del self._conn
|
||||||
|
|
||||||
self._tmpfile.write("-------- Stopping serial logging --------\n")
|
stop_marker = "-------- Stopping serial logging --------\n"
|
||||||
|
self._outfile_fh.write(stop_marker.encode('utf-8'))
|
||||||
|
self._outfile_fh.flush()
|
||||||
|
self._outfile_fh.close()
|
||||||
|
self._outfile_fh = None
|
||||||
|
|
||||||
self._collecting = False
|
self._collecting = False
|
||||||
|
|
||||||
def get_trace(self, outfile):
|
def set_output(self, output_path):
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
if self._collecting:
|
if self._collecting:
|
||||||
raise RuntimeError("get_trace was called whilst collecting")
|
raise RuntimeError("get_data was called whilst collecting")
|
||||||
|
if self.output_path is None:
|
||||||
self._tmpfile.flush()
|
raise RuntimeError("No data collected.")
|
||||||
|
return CollectorOutput([CollectorOutputEntry(self.output_path, 'file')])
|
||||||
shutil.copy(self._tmpfile.name, outfile)
|
|
||||||
|
|
||||||
self._tmpfile.close()
|
|
||||||
self._tmpfile = None
|
|
@ -1,19 +1,4 @@
|
|||||||
# Copyright 2018 ARM Limited
|
# Copyright 2024 ARM Limited
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Copyright 2018 Arm Limited
|
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -31,12 +16,10 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from shutil import copyfile
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
from tempfile import NamedTemporaryFile
|
CollectorOutputEntry)
|
||||||
|
from devlib.exception import TargetStableError, HostError
|
||||||
from devlib.exception import TargetError, HostError
|
import devlib.utils.android
|
||||||
from devlib.trace import TraceCollector
|
|
||||||
from devlib.utils.android import platform_tools
|
|
||||||
from devlib.utils.misc import memoized
|
from devlib.utils.misc import memoized
|
||||||
|
|
||||||
|
|
||||||
@ -48,7 +31,7 @@ DEFAULT_CATEGORIES = [
|
|||||||
'idle'
|
'idle'
|
||||||
]
|
]
|
||||||
|
|
||||||
class SystraceCollector(TraceCollector):
|
class SystraceCollector(CollectorBase):
|
||||||
"""
|
"""
|
||||||
A trace collector based on Systrace
|
A trace collector based on Systrace
|
||||||
|
|
||||||
@ -74,13 +57,11 @@ class SystraceCollector(TraceCollector):
|
|||||||
@property
|
@property
|
||||||
@memoized
|
@memoized
|
||||||
def available_categories(self):
|
def available_categories(self):
|
||||||
lines = subprocess.check_output([self.systrace_binary, '-l']).splitlines()
|
lines = subprocess.check_output(
|
||||||
|
[self.systrace_binary, '-l'], universal_newlines=True
|
||||||
|
).splitlines()
|
||||||
|
|
||||||
categories = []
|
return [line.split()[0] for line in lines if line]
|
||||||
for line in lines:
|
|
||||||
categories.append(line.split()[0])
|
|
||||||
|
|
||||||
return categories
|
|
||||||
|
|
||||||
def __init__(self, target,
|
def __init__(self, target,
|
||||||
categories=None,
|
categories=None,
|
||||||
@ -91,13 +72,15 @@ class SystraceCollector(TraceCollector):
|
|||||||
|
|
||||||
self.categories = categories or DEFAULT_CATEGORIES
|
self.categories = categories or DEFAULT_CATEGORIES
|
||||||
self.buffer_size = buffer_size
|
self.buffer_size = buffer_size
|
||||||
|
self.output_path = None
|
||||||
|
|
||||||
self._systrace_process = None
|
self._systrace_process = None
|
||||||
self._tmpfile = None
|
self._outfile_fh = None
|
||||||
|
|
||||||
# Try to find a systrace binary
|
# Try to find a systrace binary
|
||||||
self.systrace_binary = None
|
self.systrace_binary = None
|
||||||
|
|
||||||
|
platform_tools = devlib.utils.android.platform_tools
|
||||||
systrace_binary_path = os.path.join(platform_tools, 'systrace', 'systrace.py')
|
systrace_binary_path = os.path.join(platform_tools, 'systrace', 'systrace.py')
|
||||||
if not os.path.isfile(systrace_binary_path):
|
if not os.path.isfile(systrace_binary_path):
|
||||||
raise HostError('Could not find any systrace binary under {}'.format(platform_tools))
|
raise HostError('Could not find any systrace binary under {}'.format(platform_tools))
|
||||||
@ -109,22 +92,23 @@ class SystraceCollector(TraceCollector):
|
|||||||
if category not in self.available_categories:
|
if category not in self.available_categories:
|
||||||
message = 'Category [{}] not available for tracing'.format(category)
|
message = 'Category [{}] not available for tracing'.format(category)
|
||||||
if strict:
|
if strict:
|
||||||
raise TargetError(message)
|
raise TargetStableError(message)
|
||||||
self.logger.warning(message)
|
self.logger.warning(message)
|
||||||
|
|
||||||
self.categories = list(set(self.categories) & set(self.available_categories))
|
self.categories = list(set(self.categories) & set(self.available_categories))
|
||||||
if not self.categories:
|
if not self.categories:
|
||||||
raise TargetError('None of the requested categories are available')
|
raise TargetStableError('None of the requested categories are available')
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def _build_cmd(self):
|
def _build_cmd(self):
|
||||||
self._tmpfile = NamedTemporaryFile()
|
self._outfile_fh = open(self.output_path, 'w')
|
||||||
|
|
||||||
self.systrace_cmd = '{} -o {} -e {}'.format(
|
# pylint: disable=attribute-defined-outside-init
|
||||||
|
self.systrace_cmd = 'python2 -u {} -o {} -e {}'.format(
|
||||||
self.systrace_binary,
|
self.systrace_binary,
|
||||||
self._tmpfile.name,
|
self._outfile_fh.name,
|
||||||
self.target.adb_name
|
self.target.adb_name
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -137,13 +121,11 @@ class SystraceCollector(TraceCollector):
|
|||||||
if self._systrace_process:
|
if self._systrace_process:
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
if self._tmpfile:
|
|
||||||
self._tmpfile.close()
|
|
||||||
self._tmpfile = None
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self._systrace_process:
|
if self._systrace_process:
|
||||||
raise RuntimeError("Tracing is already underway, call stop() first")
|
raise RuntimeError("Tracing is already underway, call stop() first")
|
||||||
|
if self.output_path is None:
|
||||||
|
raise RuntimeError("Output path was not set.")
|
||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
@ -152,8 +134,11 @@ class SystraceCollector(TraceCollector):
|
|||||||
self._systrace_process = subprocess.Popen(
|
self._systrace_process = subprocess.Popen(
|
||||||
self.systrace_cmd,
|
self.systrace_cmd,
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
shell=True
|
stdout=subprocess.PIPE,
|
||||||
|
shell=True,
|
||||||
|
universal_newlines=True
|
||||||
)
|
)
|
||||||
|
self._systrace_process.stdout.read(1)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if not self._systrace_process:
|
if not self._systrace_process:
|
||||||
@ -163,11 +148,16 @@ class SystraceCollector(TraceCollector):
|
|||||||
self._systrace_process.communicate('\n')
|
self._systrace_process.communicate('\n')
|
||||||
self._systrace_process = None
|
self._systrace_process = None
|
||||||
|
|
||||||
def get_trace(self, outfile):
|
if self._outfile_fh:
|
||||||
|
self._outfile_fh.close()
|
||||||
|
self._outfile_fh = None
|
||||||
|
|
||||||
|
def set_output(self, output_path):
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
if self._systrace_process:
|
if self._systrace_process:
|
||||||
raise RuntimeError("Tracing is underway, call stop() first")
|
raise RuntimeError("Tracing is underway, call stop() first")
|
||||||
|
if self.output_path is None:
|
||||||
if not self._tmpfile:
|
raise RuntimeError("No data collected.")
|
||||||
raise RuntimeError("No tracing data available")
|
return CollectorOutput([CollectorOutputEntry(self.output_path, 'file')])
|
||||||
|
|
||||||
copyfile(self._tmpfile.name, outfile)
|
|
789
devlib/connection.py
Normal file
789
devlib/connection.py
Normal file
@ -0,0 +1,789 @@
|
|||||||
|
# Copyright 2024 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from contextlib import contextmanager, nullcontext
|
||||||
|
from shlex import quote
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import select
|
||||||
|
import fcntl
|
||||||
|
|
||||||
|
from devlib.utils.misc import InitCheckpoint, memoized
|
||||||
|
|
||||||
|
_KILL_TIMEOUT = 3
|
||||||
|
|
||||||
|
|
||||||
|
def _popen_communicate(bg, popen, input, timeout):
|
||||||
|
try:
|
||||||
|
stdout, stderr = popen.communicate(input=input, timeout=timeout)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
bg.cancel()
|
||||||
|
raise
|
||||||
|
|
||||||
|
ret = popen.returncode
|
||||||
|
if ret:
|
||||||
|
raise subprocess.CalledProcessError(
|
||||||
|
ret,
|
||||||
|
popen.args,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return (stdout, stderr)
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionBase(InitCheckpoint):
|
||||||
|
"""
|
||||||
|
Base class for all connections.
|
||||||
|
"""
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
poll_transfers=False,
|
||||||
|
start_transfer_poll_delay=30,
|
||||||
|
total_transfer_timeout=3600,
|
||||||
|
transfer_poll_period=30,
|
||||||
|
):
|
||||||
|
self._current_bg_cmds = set()
|
||||||
|
self._closed = False
|
||||||
|
self._close_lock = threading.Lock()
|
||||||
|
self.busybox = None
|
||||||
|
self.logger = logging.getLogger('Connection')
|
||||||
|
|
||||||
|
self.transfer_manager = TransferManager(
|
||||||
|
self,
|
||||||
|
start_transfer_poll_delay=start_transfer_poll_delay,
|
||||||
|
total_transfer_timeout=total_transfer_timeout,
|
||||||
|
transfer_poll_period=transfer_poll_period,
|
||||||
|
) if poll_transfers else NoopTransferManager()
|
||||||
|
|
||||||
|
|
||||||
|
def cancel_running_command(self):
|
||||||
|
bg_cmds = set(self._current_bg_cmds)
|
||||||
|
for bg_cmd in bg_cmds:
|
||||||
|
bg_cmd.cancel()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _close(self):
|
||||||
|
"""
|
||||||
|
Close the connection.
|
||||||
|
|
||||||
|
The public :meth:`close` method makes sure that :meth:`_close` will
|
||||||
|
only be called once, and will serialize accesses to it if it happens to
|
||||||
|
be called from multiple threads at once.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
|
||||||
|
def finish_bg():
|
||||||
|
bg_cmds = set(self._current_bg_cmds)
|
||||||
|
n = len(bg_cmds)
|
||||||
|
if n:
|
||||||
|
self.logger.debug(f'Canceling {n} background commands before closing connection')
|
||||||
|
for bg_cmd in bg_cmds:
|
||||||
|
bg_cmd.cancel()
|
||||||
|
|
||||||
|
# Locking the closing allows any thread to safely call close() as long
|
||||||
|
# as the connection can be closed from a thread that is not the one it
|
||||||
|
# started its life in.
|
||||||
|
with self._close_lock:
|
||||||
|
if not self._closed:
|
||||||
|
finish_bg()
|
||||||
|
self._close()
|
||||||
|
self._closed = True
|
||||||
|
|
||||||
|
# Ideally, that should not be relied upon but that will improve the chances
|
||||||
|
# of the connection being properly cleaned up when it's not in use anymore.
|
||||||
|
def __del__(self):
|
||||||
|
# Since __del__ will be called if an exception is raised in __init__
|
||||||
|
# (e.g. we cannot connect), we only run close() when we are sure
|
||||||
|
# __init__ has completed successfully.
|
||||||
|
if self.initialized:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
|
class BackgroundCommand(ABC):
|
||||||
|
"""
|
||||||
|
Allows managing a running background command using a subset of the
|
||||||
|
:class:`subprocess.Popen` API.
|
||||||
|
|
||||||
|
Instances of this class can be used as context managers, with the same
|
||||||
|
semantic as :class:`subprocess.Popen`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, conn, data_dir, cmd, as_root):
|
||||||
|
self.conn = conn
|
||||||
|
self._data_dir = data_dir
|
||||||
|
self.as_root = as_root
|
||||||
|
self.cmd = cmd
|
||||||
|
|
||||||
|
# Poll currently opened background commands on that connection to make
|
||||||
|
# them deregister themselves if they are completed. This avoids
|
||||||
|
# accumulating terminated commands and therefore leaking associated
|
||||||
|
# resources if the user is not careful and does not use the context
|
||||||
|
# manager API.
|
||||||
|
for bg_cmd in set(conn._current_bg_cmds):
|
||||||
|
try:
|
||||||
|
bg_cmd.poll()
|
||||||
|
# We don't want anything to fail here because of another command
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
conn._current_bg_cmds.add(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_factory(cls, conn, cmd, as_root, make_init_kwargs):
|
||||||
|
cmd, data_dir = cls._with_data_dir(conn, cmd)
|
||||||
|
return cls(
|
||||||
|
conn=conn,
|
||||||
|
data_dir=data_dir,
|
||||||
|
cmd=cmd,
|
||||||
|
as_root=as_root,
|
||||||
|
**make_init_kwargs(cmd),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _deregister(self):
|
||||||
|
try:
|
||||||
|
self.conn._current_bg_cmds.remove(self)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _pid_file(self):
|
||||||
|
return str(Path(self._data_dir, 'pid'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
@memoized
|
||||||
|
def _targeted_pid(self):
|
||||||
|
"""
|
||||||
|
PID of the process pointed at by ``devlib-signal-target`` command.
|
||||||
|
"""
|
||||||
|
path = quote(self._pid_file)
|
||||||
|
busybox = quote(self.conn.busybox)
|
||||||
|
|
||||||
|
def execute(cmd):
|
||||||
|
return self.conn.execute(cmd, as_root=self.as_root)
|
||||||
|
|
||||||
|
while self.poll() is None:
|
||||||
|
try:
|
||||||
|
pid = execute(f'{busybox} cat {path}')
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
time.sleep(0.01)
|
||||||
|
else:
|
||||||
|
if pid.endswith('\n'):
|
||||||
|
return int(pid.strip())
|
||||||
|
else:
|
||||||
|
# We got a partial write in the PID file
|
||||||
|
continue
|
||||||
|
|
||||||
|
raise ValueError(f'The background commmand did not use devlib-signal-target wrapper to designate which command should be the target of signals')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _with_data_dir(cls, conn, cmd):
|
||||||
|
busybox = quote(conn.busybox)
|
||||||
|
data_dir = conn.execute(f'{busybox} mktemp -d').strip()
|
||||||
|
cmd = f'_DEVLIB_BG_CMD_DATA_DIR={data_dir} exec {busybox} sh -c {quote(cmd)}'
|
||||||
|
return cmd, data_dir
|
||||||
|
|
||||||
|
def _cleanup_data_dir(self):
|
||||||
|
path = quote(self._data_dir)
|
||||||
|
busybox = quote(self.conn.busybox)
|
||||||
|
cmd = f'{busybox} rm -r {path} || true'
|
||||||
|
self.conn.execute(cmd, as_root=self.as_root)
|
||||||
|
|
||||||
|
def send_signal(self, sig):
|
||||||
|
"""
|
||||||
|
Send a POSIX signal to the background command's process group ID
|
||||||
|
(PGID).
|
||||||
|
|
||||||
|
:param signal: Signal to send.
|
||||||
|
:type signal: signal.Signals
|
||||||
|
"""
|
||||||
|
|
||||||
|
def execute(cmd):
|
||||||
|
return self.conn.execute(cmd, as_root=self.as_root)
|
||||||
|
|
||||||
|
def send(sig):
|
||||||
|
busybox = quote(self.conn.busybox)
|
||||||
|
# If the command has already completed, we don't want to send a
|
||||||
|
# signal to another process that might have gotten that PID in the
|
||||||
|
# meantime.
|
||||||
|
if self.poll() is None:
|
||||||
|
if sig in (signal.SIGTERM, signal.SIGQUIT, signal.SIGKILL):
|
||||||
|
# Use -PGID to target a process group rather than just the
|
||||||
|
# process itself. This will work in any condition and will
|
||||||
|
# not require cooperation from the command.
|
||||||
|
execute(f'{busybox} kill -{sig.value} -{self.pid}')
|
||||||
|
else:
|
||||||
|
# Other signals require cooperation from the shell command
|
||||||
|
# so that it points to a specific process using
|
||||||
|
# devlib-signal-target
|
||||||
|
pid = self._targeted_pid
|
||||||
|
execute(f'{busybox} kill -{sig.value} {pid}')
|
||||||
|
try:
|
||||||
|
return send(sig)
|
||||||
|
finally:
|
||||||
|
# Deregister if the command has finished
|
||||||
|
self.poll()
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
"""
|
||||||
|
Send SIGKILL to the background command.
|
||||||
|
"""
|
||||||
|
self.send_signal(signal.SIGKILL)
|
||||||
|
|
||||||
|
def cancel(self, kill_timeout=_KILL_TIMEOUT):
|
||||||
|
"""
|
||||||
|
Try to gracefully terminate the process by sending ``SIGTERM``, then
|
||||||
|
waiting for ``kill_timeout`` to send ``SIGKILL``.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if self.poll() is None:
|
||||||
|
return self._cancel(kill_timeout=kill_timeout)
|
||||||
|
finally:
|
||||||
|
self._deregister()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _cancel(self, kill_timeout):
|
||||||
|
"""
|
||||||
|
Method to override in subclasses to implement :meth:`cancel`.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _wait(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def wait(self):
|
||||||
|
"""
|
||||||
|
Block until the background command completes, and return its exit code.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self._wait()
|
||||||
|
finally:
|
||||||
|
self._deregister()
|
||||||
|
|
||||||
|
def communicate(self, input=b'', timeout=None):
|
||||||
|
"""
|
||||||
|
Block until the background command completes while reading stdout and stderr.
|
||||||
|
Return ``tuple(stdout, stderr)``. If the return code is non-zero,
|
||||||
|
raises a :exc:`subprocess.CalledProcessError` exception.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self._communicate(input=input, timeout=timeout)
|
||||||
|
finally:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _communicate(self, input, timeout):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _poll(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def poll(self):
|
||||||
|
"""
|
||||||
|
Return exit code if the command has exited, None otherwise.
|
||||||
|
"""
|
||||||
|
retcode = self._poll()
|
||||||
|
if retcode is not None:
|
||||||
|
self._deregister()
|
||||||
|
return retcode
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def stdin(self):
|
||||||
|
"""
|
||||||
|
File-like object connected to the background's command stdin.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def stdout(self):
|
||||||
|
"""
|
||||||
|
File-like object connected to the background's command stdout.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def stderr(self):
|
||||||
|
"""
|
||||||
|
File-like object connected to the background's command stderr.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def pid(self):
|
||||||
|
"""
|
||||||
|
Process Group ID (PGID) of the background command.
|
||||||
|
|
||||||
|
Since the command is usually wrapped in shell processes for IO
|
||||||
|
redirections, sudo etc, the PID cannot be assumed to be the actual PID
|
||||||
|
of the command passed by the user. It's is guaranteed to be a PGID
|
||||||
|
instead, which means signals sent to it as such will target all
|
||||||
|
subprocesses involved in executing that command.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _close(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""
|
||||||
|
Close all opened streams and then wait for command completion.
|
||||||
|
|
||||||
|
:returns: Exit code of the command.
|
||||||
|
|
||||||
|
.. note:: If the command is writing to its stdout/stderr, it might be
|
||||||
|
blocked on that and die when the streams are closed.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self._close()
|
||||||
|
finally:
|
||||||
|
self._deregister()
|
||||||
|
self._cleanup_data_dir()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args, **kwargs):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
|
class PopenBackgroundCommand(BackgroundCommand):
|
||||||
|
"""
|
||||||
|
:class:`subprocess.Popen`-based background command.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, conn, data_dir, cmd, as_root, popen):
|
||||||
|
super().__init__(
|
||||||
|
conn=conn,
|
||||||
|
data_dir=data_dir,
|
||||||
|
cmd=cmd,
|
||||||
|
as_root=as_root,
|
||||||
|
)
|
||||||
|
self.popen = popen
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stdin(self):
|
||||||
|
return self.popen.stdin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stdout(self):
|
||||||
|
return self.popen.stdout
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stderr(self):
|
||||||
|
return self.popen.stderr
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pid(self):
|
||||||
|
return self.popen.pid
|
||||||
|
|
||||||
|
def _wait(self):
|
||||||
|
return self.popen.wait()
|
||||||
|
|
||||||
|
def _communicate(self, input, timeout):
|
||||||
|
return _popen_communicate(self, self.popen, input, timeout)
|
||||||
|
|
||||||
|
def _poll(self):
|
||||||
|
return self.popen.poll()
|
||||||
|
|
||||||
|
def _cancel(self, kill_timeout):
|
||||||
|
popen = self.popen
|
||||||
|
os.killpg(os.getpgid(popen.pid), signal.SIGTERM)
|
||||||
|
try:
|
||||||
|
popen.wait(timeout=kill_timeout)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
os.killpg(os.getpgid(popen.pid), signal.SIGKILL)
|
||||||
|
|
||||||
|
def _close(self):
|
||||||
|
self.popen.__exit__(None, None, None)
|
||||||
|
return self.popen.returncode
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
super().__enter__()
|
||||||
|
self.popen.__enter__()
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class ParamikoBackgroundCommand(BackgroundCommand):
|
||||||
|
"""
|
||||||
|
:mod:`paramiko`-based background command.
|
||||||
|
"""
|
||||||
|
def __init__(self, conn, data_dir, cmd, as_root, chan, pid, stdin, stdout, stderr, redirect_thread):
|
||||||
|
super().__init__(
|
||||||
|
conn=conn,
|
||||||
|
data_dir=data_dir,
|
||||||
|
cmd=cmd,
|
||||||
|
as_root=as_root,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.chan = chan
|
||||||
|
self._pid = pid
|
||||||
|
self._stdin = stdin
|
||||||
|
self._stdout = stdout
|
||||||
|
self._stderr = stderr
|
||||||
|
self.redirect_thread = redirect_thread
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pid(self):
|
||||||
|
return self._pid
|
||||||
|
|
||||||
|
def _wait(self):
|
||||||
|
status = self.chan.recv_exit_status()
|
||||||
|
# Ensure that the redirection thread is finished copying the content
|
||||||
|
# from paramiko to the pipe.
|
||||||
|
self.redirect_thread.join()
|
||||||
|
return status
|
||||||
|
|
||||||
|
def _communicate(self, input, timeout):
|
||||||
|
stdout = self._stdout
|
||||||
|
stderr = self._stderr
|
||||||
|
stdin = self._stdin
|
||||||
|
chan = self.chan
|
||||||
|
|
||||||
|
# For some reason, file descriptors in the read-list of select() can
|
||||||
|
# still end up blocking in .read(), so make the non-blocking to avoid a
|
||||||
|
# deadlock. Since _communicate() will consume all input and all output
|
||||||
|
# until the command dies, we can do whatever we want with the pipe
|
||||||
|
# without affecting external users.
|
||||||
|
for s in (stdout, stderr):
|
||||||
|
fcntl.fcntl(s.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
|
||||||
|
|
||||||
|
out = {stdout: [], stderr: []}
|
||||||
|
ret = None
|
||||||
|
can_send = True
|
||||||
|
|
||||||
|
select_timeout = 1
|
||||||
|
if timeout is not None:
|
||||||
|
select_timeout = min(select_timeout, 1)
|
||||||
|
|
||||||
|
def create_out():
|
||||||
|
return (
|
||||||
|
b''.join(out[stdout]),
|
||||||
|
b''.join(out[stderr])
|
||||||
|
)
|
||||||
|
|
||||||
|
start = time.monotonic()
|
||||||
|
|
||||||
|
while ret is None:
|
||||||
|
# Even if ret is not None anymore, we need to drain the streams
|
||||||
|
ret = self.poll()
|
||||||
|
|
||||||
|
if timeout is not None and ret is None and time.monotonic() - start >= timeout:
|
||||||
|
self.cancel()
|
||||||
|
_stdout, _stderr = create_out()
|
||||||
|
raise subprocess.TimeoutExpired(self.cmd, timeout, _stdout, _stderr)
|
||||||
|
|
||||||
|
can_send &= (not chan.closed) & bool(input)
|
||||||
|
wlist = [chan] if can_send else []
|
||||||
|
|
||||||
|
if can_send and chan.send_ready():
|
||||||
|
try:
|
||||||
|
n = chan.send(input)
|
||||||
|
# stdin might have been closed already
|
||||||
|
except OSError:
|
||||||
|
can_send = False
|
||||||
|
chan.shutdown_write()
|
||||||
|
else:
|
||||||
|
input = input[n:]
|
||||||
|
if not input:
|
||||||
|
# Send EOF on stdin
|
||||||
|
chan.shutdown_write()
|
||||||
|
|
||||||
|
rs, ws, _ = select.select(
|
||||||
|
[x for x in (stdout, stderr) if not x.closed],
|
||||||
|
wlist,
|
||||||
|
[],
|
||||||
|
select_timeout,
|
||||||
|
)
|
||||||
|
|
||||||
|
for r in rs:
|
||||||
|
chunk = r.read()
|
||||||
|
if chunk:
|
||||||
|
out[r].append(chunk)
|
||||||
|
|
||||||
|
_stdout, _stderr = create_out()
|
||||||
|
|
||||||
|
if ret:
|
||||||
|
raise subprocess.CalledProcessError(
|
||||||
|
ret,
|
||||||
|
self.cmd,
|
||||||
|
_stdout,
|
||||||
|
_stderr,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return (_stdout, _stderr)
|
||||||
|
|
||||||
|
def _poll(self):
|
||||||
|
# Wait for the redirection thread to finish, otherwise we would
|
||||||
|
# indicate the caller that the command is finished and that the streams
|
||||||
|
# are safe to drain, but actually the redirection thread is not
|
||||||
|
# finished yet, which would end up in lost data.
|
||||||
|
if self.redirect_thread.is_alive():
|
||||||
|
return None
|
||||||
|
elif self.chan.exit_status_ready():
|
||||||
|
return self.wait()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _cancel(self, kill_timeout):
|
||||||
|
self.send_signal(signal.SIGTERM)
|
||||||
|
# Check if the command terminated quickly
|
||||||
|
time.sleep(10e-3)
|
||||||
|
# Otherwise wait for the full timeout and kill it
|
||||||
|
if self.poll() is None:
|
||||||
|
time.sleep(kill_timeout)
|
||||||
|
self.send_signal(signal.SIGKILL)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stdin(self):
|
||||||
|
return self._stdin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stdout(self):
|
||||||
|
return self._stdout
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stderr(self):
|
||||||
|
return self._stderr
|
||||||
|
|
||||||
|
def _close(self):
|
||||||
|
for x in (self.stdin, self.stdout, self.stderr):
|
||||||
|
if x is not None:
|
||||||
|
x.close()
|
||||||
|
|
||||||
|
exit_code = self.wait()
|
||||||
|
thread = self.redirect_thread
|
||||||
|
if thread:
|
||||||
|
thread.join()
|
||||||
|
|
||||||
|
return exit_code
|
||||||
|
|
||||||
|
|
||||||
|
class AdbBackgroundCommand(BackgroundCommand):
|
||||||
|
"""
|
||||||
|
``adb``-based background command.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, conn, data_dir, cmd, as_root, adb_popen, pid):
|
||||||
|
super().__init__(
|
||||||
|
conn=conn,
|
||||||
|
data_dir=data_dir,
|
||||||
|
cmd=cmd,
|
||||||
|
as_root=as_root,
|
||||||
|
)
|
||||||
|
self.adb_popen = adb_popen
|
||||||
|
self._pid = pid
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stdin(self):
|
||||||
|
return self.adb_popen.stdin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stdout(self):
|
||||||
|
return self.adb_popen.stdout
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stderr(self):
|
||||||
|
return self.adb_popen.stderr
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pid(self):
|
||||||
|
return self._pid
|
||||||
|
|
||||||
|
def _wait(self):
|
||||||
|
return self.adb_popen.wait()
|
||||||
|
|
||||||
|
def _communicate(self, input, timeout):
|
||||||
|
return _popen_communicate(self, self.adb_popen, input, timeout)
|
||||||
|
|
||||||
|
def _poll(self):
|
||||||
|
return self.adb_popen.poll()
|
||||||
|
|
||||||
|
def _cancel(self, kill_timeout):
|
||||||
|
self.send_signal(signal.SIGTERM)
|
||||||
|
try:
|
||||||
|
self.adb_popen.wait(timeout=kill_timeout)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
self.send_signal(signal.SIGKILL)
|
||||||
|
self.adb_popen.kill()
|
||||||
|
|
||||||
|
def _close(self):
|
||||||
|
self.adb_popen.__exit__(None, None, None)
|
||||||
|
return self.adb_popen.returncode
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
super().__enter__()
|
||||||
|
self.adb_popen.__enter__()
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class TransferManager:
|
||||||
|
def __init__(self, conn, transfer_poll_period=30, start_transfer_poll_delay=30, total_transfer_timeout=3600):
|
||||||
|
self.conn = conn
|
||||||
|
self.transfer_poll_period = transfer_poll_period
|
||||||
|
self.total_transfer_timeout = total_transfer_timeout
|
||||||
|
self.start_transfer_poll_delay = start_transfer_poll_delay
|
||||||
|
|
||||||
|
self.logger = logging.getLogger('FileTransfer')
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def manage(self, sources, dest, direction, handle):
|
||||||
|
excep = None
|
||||||
|
stop_thread = threading.Event()
|
||||||
|
|
||||||
|
def monitor():
|
||||||
|
nonlocal excep
|
||||||
|
|
||||||
|
def cancel(reason):
|
||||||
|
self.logger.warning(
|
||||||
|
f'Cancelling file transfer {sources} -> {dest} due to: {reason}'
|
||||||
|
)
|
||||||
|
handle.cancel()
|
||||||
|
|
||||||
|
start_t = time.monotonic()
|
||||||
|
stop_thread.wait(self.start_transfer_poll_delay)
|
||||||
|
while not stop_thread.wait(self.transfer_poll_period):
|
||||||
|
if not handle.isactive():
|
||||||
|
cancel(reason='transfer inactive')
|
||||||
|
elif time.monotonic() - start_t > self.total_transfer_timeout:
|
||||||
|
cancel(reason='transfer timed out')
|
||||||
|
excep = TimeoutError(f'{direction}: {sources} -> {dest}')
|
||||||
|
|
||||||
|
m_thread = threading.Thread(target=monitor, daemon=True)
|
||||||
|
try:
|
||||||
|
m_thread.start()
|
||||||
|
yield self
|
||||||
|
finally:
|
||||||
|
stop_thread.set()
|
||||||
|
m_thread.join()
|
||||||
|
if excep is not None:
|
||||||
|
raise excep
|
||||||
|
|
||||||
|
|
||||||
|
class NoopTransferManager:
|
||||||
|
def manage(self, *args, **kwargs):
|
||||||
|
return nullcontext(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TransferHandleBase(ABC):
|
||||||
|
def __init__(self, manager):
|
||||||
|
self.manager = manager
|
||||||
|
|
||||||
|
@property
|
||||||
|
def logger(self):
|
||||||
|
return self.manager.logger
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def isactive(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def cancel(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PopenTransferHandle(TransferHandleBase):
|
||||||
|
def __init__(self, popen, dest, direction, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if direction == 'push':
|
||||||
|
sample_size = self._push_dest_size
|
||||||
|
elif direction == 'pull':
|
||||||
|
sample_size = self._pull_dest_size
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown direction: {direction}')
|
||||||
|
|
||||||
|
self.sample_size = lambda: sample_size(dest)
|
||||||
|
|
||||||
|
self.popen = popen
|
||||||
|
self.last_sample = 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _pull_dest_size(dest):
|
||||||
|
if os.path.isdir(dest):
|
||||||
|
return sum(
|
||||||
|
os.stat(os.path.join(dirpath, f)).st_size
|
||||||
|
for dirpath, _, fnames in os.walk(dest)
|
||||||
|
for f in fnames
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return os.stat(dest).st_size
|
||||||
|
|
||||||
|
def _push_dest_size(self, dest):
|
||||||
|
conn = self.manager.conn
|
||||||
|
cmd = '{} du -s -- {}'.format(quote(conn.busybox), quote(dest))
|
||||||
|
out = conn.execute(cmd)
|
||||||
|
return int(out.split()[0])
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
self.popen.terminate()
|
||||||
|
|
||||||
|
def isactive(self):
|
||||||
|
try:
|
||||||
|
curr_size = self.sample_size()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.debug(f'File size polling failed: {e}')
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.debug(f'Polled file transfer, destination size: {curr_size}')
|
||||||
|
if curr_size:
|
||||||
|
active = curr_size > self.last_sample
|
||||||
|
self.last_sample = curr_size
|
||||||
|
return active
|
||||||
|
# If the file is empty it will never grow in size, so we assume
|
||||||
|
# everything is going well.
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class SSHTransferHandle(TransferHandleBase):
|
||||||
|
|
||||||
|
def __init__(self, handle, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# SFTPClient or SSHClient
|
||||||
|
self.handle = handle
|
||||||
|
|
||||||
|
self.progressed = False
|
||||||
|
self.transferred = 0
|
||||||
|
self.to_transfer = 0
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
self.handle.close()
|
||||||
|
|
||||||
|
def isactive(self):
|
||||||
|
progressed = self.progressed
|
||||||
|
if progressed:
|
||||||
|
self.progressed = False
|
||||||
|
pc = (self.transferred / self.to_transfer) * 100
|
||||||
|
self.logger.debug(
|
||||||
|
f'Polled transfer: {pc:.2f}% [{self.transferred}B/{self.to_transfer}B]'
|
||||||
|
)
|
||||||
|
return progressed
|
||||||
|
|
||||||
|
def progress_cb(self, transferred, to_transfer):
|
||||||
|
self.progressed = True
|
||||||
|
self.transferred = transferred
|
||||||
|
self.to_transfer = to_transfer
|
@ -36,25 +36,28 @@ class DerivedMetric(object):
|
|||||||
msg = 'Unknown measurement type: {}'
|
msg = 'Unknown measurement type: {}'
|
||||||
raise ValueError(msg.format(measurement_type))
|
raise ValueError(msg.format(measurement_type))
|
||||||
|
|
||||||
def __cmp__(self, other):
|
|
||||||
if hasattr(other, 'value'):
|
|
||||||
return cmp(self.value, other.value)
|
|
||||||
else:
|
|
||||||
return cmp(self.value, other)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.units:
|
if self.units:
|
||||||
return '{}: {} {}'.format(self.name, self.value, self.units)
|
return '{}: {} {}'.format(self.name, self.value, self.units)
|
||||||
else:
|
else:
|
||||||
return '{}: {}'.format(self.name, self.value)
|
return '{}: {}'.format(self.name, self.value)
|
||||||
|
|
||||||
|
# pylint: disable=undefined-variable
|
||||||
|
def __cmp__(self, other):
|
||||||
|
if hasattr(other, 'value'):
|
||||||
|
return cmp(self.value, other.value)
|
||||||
|
else:
|
||||||
|
return cmp(self.value, other)
|
||||||
|
|
||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
||||||
|
|
||||||
class DerivedMeasurements(object):
|
class DerivedMeasurements(object):
|
||||||
|
|
||||||
|
# pylint: disable=no-self-use,unused-argument
|
||||||
def process(self, measurements_csv):
|
def process(self, measurements_csv):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
# pylint: disable=no-self-use
|
||||||
def process_raw(self, *args):
|
def process_raw(self, *args):
|
||||||
return []
|
return []
|
||||||
|
@ -12,15 +12,15 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from __future__ import division
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from devlib import DerivedMeasurements, DerivedMetric
|
from devlib.derived import DerivedMeasurements, DerivedMetric
|
||||||
from devlib.instrument import MEASUREMENT_TYPES, InstrumentChannel
|
from devlib.instrument import MEASUREMENT_TYPES
|
||||||
|
|
||||||
|
|
||||||
class DerivedEnergyMeasurements(DerivedMeasurements):
|
class DerivedEnergyMeasurements(DerivedMeasurements):
|
||||||
|
|
||||||
|
# pylint: disable=too-many-locals,too-many-branches
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def process(measurements_csv):
|
def process(measurements_csv):
|
||||||
|
|
||||||
|
@ -13,9 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@ -24,8 +22,9 @@ except ImportError:
|
|||||||
|
|
||||||
from past.builtins import basestring
|
from past.builtins import basestring
|
||||||
|
|
||||||
from devlib import DerivedMeasurements, DerivedMetric, MeasurementsCsv, InstrumentChannel
|
from devlib.derived import DerivedMeasurements, DerivedMetric
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
|
from devlib.instrument import MeasurementsCsv
|
||||||
from devlib.utils.csvutil import csvwriter
|
from devlib.utils.csvutil import csvwriter
|
||||||
from devlib.utils.rendering import gfxinfo_get_last_dump, VSYNC_INTERVAL
|
from devlib.utils.rendering import gfxinfo_get_last_dump, VSYNC_INTERVAL
|
||||||
from devlib.utils.types import numeric
|
from devlib.utils.types import numeric
|
||||||
@ -45,6 +44,7 @@ class DerivedFpsStats(DerivedMeasurements):
|
|||||||
if filename is not None and os.sep in filename:
|
if filename is not None and os.sep in filename:
|
||||||
raise ValueError('filename cannot be a path (cannot countain "{}"'.format(os.sep))
|
raise ValueError('filename cannot be a path (cannot countain "{}"'.format(os.sep))
|
||||||
|
|
||||||
|
# pylint: disable=no-member
|
||||||
def process(self, measurements_csv):
|
def process(self, measurements_csv):
|
||||||
if isinstance(measurements_csv, basestring):
|
if isinstance(measurements_csv, basestring):
|
||||||
measurements_csv = MeasurementsCsv(measurements_csv)
|
measurements_csv = MeasurementsCsv(measurements_csv)
|
||||||
@ -65,6 +65,7 @@ class DerivedFpsStats(DerivedMeasurements):
|
|||||||
|
|
||||||
class DerivedGfxInfoStats(DerivedFpsStats):
|
class DerivedGfxInfoStats(DerivedFpsStats):
|
||||||
|
|
||||||
|
#pylint: disable=arguments-differ
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def process_raw(filepath, *args):
|
def process_raw(filepath, *args):
|
||||||
metrics = []
|
metrics = []
|
||||||
@ -104,17 +105,17 @@ class DerivedGfxInfoStats(DerivedFpsStats):
|
|||||||
frame_count += 1
|
frame_count += 1
|
||||||
|
|
||||||
if start_vsync is None:
|
if start_vsync is None:
|
||||||
start_vsync = frame_data.Vsync_time_us
|
start_vsync = frame_data.Vsync_time_ns
|
||||||
end_vsync = frame_data.Vsync_time_us
|
end_vsync = frame_data.Vsync_time_ns
|
||||||
|
|
||||||
frame_time = frame_data.FrameCompleted_time_us - frame_data.IntendedVsync_time_us
|
frame_time = frame_data.FrameCompleted_time_ns - frame_data.IntendedVsync_time_ns
|
||||||
pff = 1e9 / frame_time
|
pff = 1e9 / frame_time
|
||||||
if pff > self.drop_threshold:
|
if pff > self.drop_threshold:
|
||||||
per_frame_fps.append([pff])
|
per_frame_fps.append([pff])
|
||||||
|
|
||||||
if frame_count:
|
if frame_count:
|
||||||
duration = end_vsync - start_vsync
|
duration = end_vsync - start_vsync
|
||||||
fps = (1e6 * frame_count) / float(duration)
|
fps = (1e9 * frame_count) / float(duration)
|
||||||
else:
|
else:
|
||||||
duration = 0
|
duration = 0
|
||||||
fps = 0
|
fps = 0
|
||||||
@ -131,15 +132,15 @@ class DerivedGfxInfoStats(DerivedFpsStats):
|
|||||||
def _process_with_pandas(self, measurements_csv):
|
def _process_with_pandas(self, measurements_csv):
|
||||||
data = pd.read_csv(measurements_csv.path)
|
data = pd.read_csv(measurements_csv.path)
|
||||||
data = data[data.Flags_flags == 0]
|
data = data[data.Flags_flags == 0]
|
||||||
frame_time = data.FrameCompleted_time_us - data.IntendedVsync_time_us
|
frame_time = data.FrameCompleted_time_ns - data.IntendedVsync_time_ns
|
||||||
per_frame_fps = (1e6 / frame_time)
|
per_frame_fps = (1e9 / frame_time)
|
||||||
keep_filter = per_frame_fps > self.drop_threshold
|
keep_filter = per_frame_fps > self.drop_threshold
|
||||||
per_frame_fps = per_frame_fps[keep_filter]
|
per_frame_fps = per_frame_fps[keep_filter]
|
||||||
per_frame_fps.name = 'fps'
|
per_frame_fps.name = 'fps'
|
||||||
|
|
||||||
frame_count = data.index.size
|
frame_count = data.index.size
|
||||||
if frame_count > 1:
|
if frame_count > 1:
|
||||||
duration = data.Vsync_time_us.iloc[-1] - data.Vsync_time_us.iloc[0]
|
duration = data.Vsync_time_ns.iloc[-1] - data.Vsync_time_ns.iloc[0]
|
||||||
fps = (1e9 * frame_count) / float(duration)
|
fps = (1e9 * frame_count) / float(duration)
|
||||||
else:
|
else:
|
||||||
duration = 0
|
duration = 0
|
||||||
@ -155,6 +156,7 @@ class DerivedGfxInfoStats(DerivedFpsStats):
|
|||||||
|
|
||||||
class DerivedSurfaceFlingerStats(DerivedFpsStats):
|
class DerivedSurfaceFlingerStats(DerivedFpsStats):
|
||||||
|
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
def _process_with_pandas(self, measurements_csv):
|
def _process_with_pandas(self, measurements_csv):
|
||||||
data = pd.read_csv(measurements_csv.path)
|
data = pd.read_csv(measurements_csv.path)
|
||||||
|
|
||||||
@ -193,7 +195,7 @@ class DerivedSurfaceFlingerStats(DerivedFpsStats):
|
|||||||
janks = 0
|
janks = 0
|
||||||
not_at_vsync = 0
|
not_at_vsync = 0
|
||||||
|
|
||||||
janks_pc = 0 if frame_count == 0 else janks * 100 / frame_count
|
janks_pc = 0 if frame_count == 0 else janks * 100 / frame_count
|
||||||
|
|
||||||
return [DerivedMetric('fps', fps, 'fps'),
|
return [DerivedMetric('fps', fps, 'fps'),
|
||||||
DerivedMetric('total_frames', frame_count, 'frames'),
|
DerivedMetric('total_frames', frame_count, 'frames'),
|
||||||
@ -202,6 +204,7 @@ class DerivedSurfaceFlingerStats(DerivedFpsStats):
|
|||||||
DerivedMetric('janks_pc', janks_pc, 'percent'),
|
DerivedMetric('janks_pc', janks_pc, 'percent'),
|
||||||
DerivedMetric('missed_vsync', not_at_vsync, 'count')]
|
DerivedMetric('missed_vsync', not_at_vsync, 'count')]
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument,no-self-use
|
||||||
def _process_without_pandas(self, measurements_csv):
|
def _process_without_pandas(self, measurements_csv):
|
||||||
# Given that SurfaceFlinger has been deprecated in favor of GfxInfo,
|
# Given that SurfaceFlinger has been deprecated in favor of GfxInfo,
|
||||||
# it does not seem worth it implementing this.
|
# it does not seem worth it implementing this.
|
||||||
|
@ -13,13 +13,44 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
class DevlibError(Exception):
|
class DevlibError(Exception):
|
||||||
"""Base class for all Devlib exceptions."""
|
"""Base class for all Devlib exceptions."""
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
message = args[0] if args else None
|
||||||
|
self._message = message
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def message(self):
|
def message(self):
|
||||||
if self.args:
|
try:
|
||||||
return self.args[0]
|
msg = self._message
|
||||||
return str(self)
|
except AttributeError:
|
||||||
|
msg = None
|
||||||
|
|
||||||
|
if msg is None:
|
||||||
|
return str(self)
|
||||||
|
else:
|
||||||
|
return self._message
|
||||||
|
|
||||||
|
|
||||||
|
class DevlibStableError(DevlibError):
|
||||||
|
"""Non transient target errors, that are not subject to random variations
|
||||||
|
in the environment and can be reliably linked to for example a missing
|
||||||
|
feature on a target."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DevlibTransientError(DevlibError):
|
||||||
|
"""Exceptions inheriting from ``DevlibTransientError`` represent random
|
||||||
|
transient events that are usually related to issues in the environment, as
|
||||||
|
opposed to programming errors, for example network failures or
|
||||||
|
timeout-related exceptions. When the error could come from
|
||||||
|
indistinguishable transient or non-transient issue, it can generally be
|
||||||
|
assumed that the configuration is correct and therefore, a transient
|
||||||
|
exception is raised."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TargetError(DevlibError):
|
class TargetError(DevlibError):
|
||||||
@ -27,7 +58,56 @@ class TargetError(DevlibError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TargetNotRespondingError(DevlibError):
|
class TargetTransientError(TargetError, DevlibTransientError):
|
||||||
|
"""Transient target errors that can happen randomly when everything is
|
||||||
|
properly configured."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TargetStableError(TargetError, DevlibStableError):
|
||||||
|
"""Non-transient target errors that can be linked to a programming error or
|
||||||
|
a configuration issue, and is not influenced by non-controllable parameters
|
||||||
|
such as network issues."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TargetCalledProcessError(subprocess.CalledProcessError, TargetError):
|
||||||
|
"""Exception raised when a command executed on the target fails."""
|
||||||
|
def __str__(self):
|
||||||
|
msg = super().__str__()
|
||||||
|
def decode(s):
|
||||||
|
try:
|
||||||
|
s = s.decode()
|
||||||
|
except AttributeError:
|
||||||
|
s = str(s)
|
||||||
|
|
||||||
|
return s.strip()
|
||||||
|
|
||||||
|
if self.stdout is not None and self.stderr is None:
|
||||||
|
out = ['OUTPUT: {}'.format(decode(self.output))]
|
||||||
|
else:
|
||||||
|
out = [
|
||||||
|
'STDOUT: {}'.format(decode(self.output)) if self.output is not None else '',
|
||||||
|
'STDERR: {}'.format(decode(self.stderr)) if self.stderr is not None else '',
|
||||||
|
]
|
||||||
|
|
||||||
|
return '\n'.join((
|
||||||
|
msg,
|
||||||
|
*out,
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
class TargetStableCalledProcessError(TargetCalledProcessError, TargetStableError):
|
||||||
|
"""Variant of :exc:`devlib.exception.TargetCalledProcessError` that indicates a stable error"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TargetTransientCalledProcessError(TargetCalledProcessError, TargetTransientError):
|
||||||
|
"""Variant of :exc:`devlib.exception.TargetCalledProcessError` that indicates a transient error"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TargetNotRespondingError(TargetTransientError):
|
||||||
"""The target is unresponsive."""
|
"""The target is unresponsive."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -37,7 +117,8 @@ class HostError(DevlibError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TimeoutError(DevlibError):
|
# pylint: disable=redefined-builtin
|
||||||
|
class TimeoutError(DevlibTransientError):
|
||||||
"""Raised when a subprocess command times out. This is basically a ``DevlibError``-derived version
|
"""Raised when a subprocess command times out. This is basically a ``DevlibError``-derived version
|
||||||
of ``subprocess.CalledProcessError``, the thinking being that while a timeout could be due to
|
of ``subprocess.CalledProcessError``, the thinking being that while a timeout could be due to
|
||||||
programming error (e.g. not setting long enough timers), it is often due to some failure in the
|
programming error (e.g. not setting long enough timers), it is often due to some failure in the
|
||||||
@ -73,19 +154,37 @@ class WorkerThreadError(DevlibError):
|
|||||||
super(WorkerThreadError, self).__init__(message)
|
super(WorkerThreadError, self).__init__(message)
|
||||||
|
|
||||||
|
|
||||||
|
class KernelConfigKeyError(KeyError, IndexError, DevlibError):
|
||||||
|
"""
|
||||||
|
Exception raised when a kernel config option cannot be found.
|
||||||
|
|
||||||
|
It inherits from :exc:`IndexError` for backward compatibility, and
|
||||||
|
:exc:`KeyError` to behave like a regular mapping.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def get_traceback(exc=None):
|
def get_traceback(exc=None):
|
||||||
"""
|
"""
|
||||||
Returns the string with the traceback for the specifiec exc
|
Returns the string with the traceback for the specifiec exc
|
||||||
object, or for the current exception exc is not specified.
|
object, or for the current exception exc is not specified.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import io, traceback, sys
|
import io, traceback, sys # pylint: disable=multiple-imports
|
||||||
if exc is None:
|
if exc is None:
|
||||||
exc = sys.exc_info()
|
exc = sys.exc_info()
|
||||||
if not exc:
|
if not exc:
|
||||||
return None
|
return None
|
||||||
tb = exc[2]
|
tb = exc[2]
|
||||||
sio = io.BytesIO()
|
sio = io.StringIO()
|
||||||
traceback.print_tb(tb, file=sio)
|
traceback.print_tb(tb, file=sio)
|
||||||
del tb # needs to be done explicitly see: http://docs.python.org/2/library/sys.html#sys.exc_info
|
del tb # needs to be done explicitly see: http://docs.python.org/2/library/sys.html#sys.exc_info
|
||||||
return sio.getvalue()
|
return sio.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class AdbRootError(TargetStableError):
|
||||||
|
"""
|
||||||
|
Exception raised when it is not safe to use ``adb root`` or ``adb unroot``
|
||||||
|
because other connections are known to be active, and changing rootness
|
||||||
|
requires restarting the server.
|
||||||
|
"""
|
||||||
|
146
devlib/host.py
146
devlib/host.py
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2015-2017 ARM Limited
|
# Copyright 2015-2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,79 +12,173 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from glob import iglob
|
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
|
from shlex import quote
|
||||||
|
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import (
|
||||||
|
TargetStableError, TargetTransientCalledProcessError, TargetStableCalledProcessError
|
||||||
|
)
|
||||||
from devlib.utils.misc import check_output
|
from devlib.utils.misc import check_output
|
||||||
|
from devlib.connection import ConnectionBase, PopenBackgroundCommand
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 8):
|
||||||
|
def copy_tree(src, dst):
|
||||||
|
from shutil import copy, copytree
|
||||||
|
copytree(
|
||||||
|
src,
|
||||||
|
dst,
|
||||||
|
# dirs_exist_ok=True only exists in Python >= 3.8
|
||||||
|
dirs_exist_ok=True,
|
||||||
|
# Do not copy creation and modification time to behave like other
|
||||||
|
# targets.
|
||||||
|
copy_function=copy
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
def copy_tree(src, dst):
|
||||||
|
from distutils.dir_util import copy_tree
|
||||||
|
# Mirror the behavior of all other targets which only copy the
|
||||||
|
# content without metadata
|
||||||
|
copy_tree(src, dst, preserve_mode=False, preserve_times=False)
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_BIN_DIRECTORY = os.path.join(os.path.dirname(__file__), 'bin')
|
PACKAGE_BIN_DIRECTORY = os.path.join(os.path.dirname(__file__), 'bin')
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=redefined-outer-name
|
||||||
def kill_children(pid, signal=signal.SIGKILL):
|
def kill_children(pid, signal=signal.SIGKILL):
|
||||||
with open('/proc/{0}/task/{0}/children'.format(pid), 'r') as fd:
|
with open('/proc/{0}/task/{0}/children'.format(pid), 'r') as fd:
|
||||||
for cpid in map(int, fd.read().strip().split()):
|
for cpid in map(int, fd.read().strip().split()):
|
||||||
kill_children(cpid, signal)
|
kill_children(cpid, signal)
|
||||||
os.kill(cpid, signal)
|
os.kill(cpid, signal)
|
||||||
|
|
||||||
class LocalConnection(object):
|
|
||||||
|
class LocalConnection(ConnectionBase):
|
||||||
|
|
||||||
name = 'local'
|
name = 'local'
|
||||||
|
host = 'localhost'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connected_as_root(self):
|
||||||
|
if self._connected_as_root is None:
|
||||||
|
result = self.execute('id', as_root=False)
|
||||||
|
self._connected_as_root = 'uid=0(' in result
|
||||||
|
return self._connected_as_root
|
||||||
|
|
||||||
|
@connected_as_root.setter
|
||||||
|
def connected_as_root(self, state):
|
||||||
|
self._connected_as_root = state
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
def __init__(self, platform=None, keep_password=True, unrooted=False,
|
def __init__(self, platform=None, keep_password=True, unrooted=False,
|
||||||
password=None, timeout=None):
|
password=None, timeout=None):
|
||||||
|
super().__init__()
|
||||||
|
self._connected_as_root = None
|
||||||
self.logger = logging.getLogger('local_connection')
|
self.logger = logging.getLogger('local_connection')
|
||||||
self.keep_password = keep_password
|
self.keep_password = keep_password
|
||||||
self.unrooted = unrooted
|
self.unrooted = unrooted
|
||||||
self.password = password
|
self.password = password
|
||||||
|
|
||||||
def push(self, source, dest, timeout=None, as_root=False): # pylint: disable=unused-argument
|
|
||||||
self.logger.debug('cp {} {}'.format(source, dest))
|
|
||||||
shutil.copy(source, dest)
|
|
||||||
|
|
||||||
def pull(self, source, dest, timeout=None, as_root=False): # pylint: disable=unused-argument
|
def _copy_path(self, source, dest):
|
||||||
self.logger.debug('cp {} {}'.format(source, dest))
|
self.logger.debug('copying {} to {}'.format(source, dest))
|
||||||
if ('*' in source or '?' in source) and os.path.isdir(dest):
|
if os.path.isdir(source):
|
||||||
# Pull all files matching a wildcard expression
|
copy_tree(source, dest)
|
||||||
for each_source in iglob(source):
|
|
||||||
shutil.copy(each_source, dest)
|
|
||||||
else:
|
else:
|
||||||
shutil.copy(source, dest)
|
shutil.copy(source, dest)
|
||||||
|
|
||||||
|
def _copy_paths(self, sources, dest):
|
||||||
|
for source in sources:
|
||||||
|
self._copy_path(source, dest)
|
||||||
|
|
||||||
|
def push(self, sources, dest, timeout=None, as_root=False): # pylint: disable=unused-argument
|
||||||
|
self._copy_paths(sources, dest)
|
||||||
|
|
||||||
|
def pull(self, sources, dest, timeout=None, as_root=False): # pylint: disable=unused-argument
|
||||||
|
self._copy_paths(sources, dest)
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
def execute(self, command, timeout=None, check_exit_code=True,
|
def execute(self, command, timeout=None, check_exit_code=True,
|
||||||
as_root=False, strip_colors=True):
|
as_root=False, strip_colors=True, will_succeed=False):
|
||||||
self.logger.debug(command)
|
self.logger.debug(command)
|
||||||
if as_root:
|
use_sudo = as_root and not self.connected_as_root
|
||||||
|
if use_sudo:
|
||||||
if self.unrooted:
|
if self.unrooted:
|
||||||
raise TargetError('unrooted')
|
raise TargetStableError('unrooted')
|
||||||
password = self._get_password()
|
password = self._get_password()
|
||||||
command = 'echo \'{}\' | sudo -S '.format(password) + command
|
# Empty prompt with -p '' to avoid adding a leading space to the
|
||||||
|
# output.
|
||||||
|
command = "echo {} | sudo -k -p '' -S -- sh -c {}".format(quote(password), quote(command))
|
||||||
ignore = None if check_exit_code else 'all'
|
ignore = None if check_exit_code else 'all'
|
||||||
try:
|
try:
|
||||||
return check_output(command, shell=True, timeout=timeout, ignore=ignore)[0]
|
stdout, stderr = check_output(command, shell=True, timeout=timeout, ignore=ignore)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'.format(
|
cls = TargetTransientCalledProcessError if will_succeed else TargetStableCalledProcessError
|
||||||
e.returncode, command, e.output)
|
raise cls(
|
||||||
raise TargetError(message)
|
e.returncode,
|
||||||
|
command,
|
||||||
|
e.output,
|
||||||
|
e.stderr,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove the one-character prompt of sudo -S -p
|
||||||
|
if use_sudo and stderr:
|
||||||
|
stderr = stderr[1:]
|
||||||
|
|
||||||
|
return stdout + stderr
|
||||||
|
|
||||||
def background(self, command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, as_root=False):
|
def background(self, command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, as_root=False):
|
||||||
if as_root:
|
if as_root and not self.connected_as_root:
|
||||||
if self.unrooted:
|
if self.unrooted:
|
||||||
raise TargetError('unrooted')
|
raise TargetStableError('unrooted')
|
||||||
password = self._get_password()
|
password = self._get_password()
|
||||||
command = 'echo \'{}\' | sudo -S '.format(password) + command
|
# Empty prompt with -p '' to avoid adding a leading space to the
|
||||||
return subprocess.Popen(command, stdout=stdout, stderr=stderr, shell=True)
|
# output.
|
||||||
|
command = "echo {} | sudo -k -p '' -S -- sh -c {}".format(quote(password), quote(command))
|
||||||
|
|
||||||
def close(self):
|
# Make sure to get a new PGID so PopenBackgroundCommand() can kill
|
||||||
|
# all sub processes that could be started without troubles.
|
||||||
|
def preexec_fn():
|
||||||
|
os.setpgrp()
|
||||||
|
|
||||||
|
def make_init_kwargs(command):
|
||||||
|
popen = subprocess.Popen(
|
||||||
|
command,
|
||||||
|
stdout=stdout,
|
||||||
|
stderr=stderr,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
shell=True,
|
||||||
|
preexec_fn=preexec_fn,
|
||||||
|
)
|
||||||
|
return dict(
|
||||||
|
popen=popen,
|
||||||
|
)
|
||||||
|
|
||||||
|
return PopenBackgroundCommand.from_factory(
|
||||||
|
conn=self,
|
||||||
|
cmd=command,
|
||||||
|
as_root=as_root,
|
||||||
|
make_init_kwargs=make_init_kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _close(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def cancel_running_command(self):
|
def cancel_running_command(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def wait_for_device(self, timeout=30):
|
||||||
|
return
|
||||||
|
|
||||||
|
def reboot_bootloader(self, timeout=30):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def _get_password(self):
|
def _get_password(self):
|
||||||
if self.password:
|
if self.password:
|
||||||
return self.password
|
return self.password
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from __future__ import division
|
|
||||||
import logging
|
import logging
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
@ -58,6 +57,7 @@ class MeasurementType(object):
|
|||||||
raise ValueError(msg.format(self.name, to.name))
|
raise ValueError(msg.format(self.name, to.name))
|
||||||
return self.conversions[to.name](value)
|
return self.conversions[to.name](value)
|
||||||
|
|
||||||
|
# pylint: disable=undefined-variable
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
if isinstance(other, MeasurementType):
|
if isinstance(other, MeasurementType):
|
||||||
other = other.name
|
other = other.name
|
||||||
@ -96,20 +96,30 @@ _measurement_types = [
|
|||||||
# covert without being familar with individual instruments.
|
# covert without being familar with individual instruments.
|
||||||
MeasurementType('time', 'seconds', 'time',
|
MeasurementType('time', 'seconds', 'time',
|
||||||
conversions={
|
conversions={
|
||||||
'time_us': lambda x: x * 1000000,
|
'time_us': lambda x: x * 1e6,
|
||||||
'time_ms': lambda x: x * 1000,
|
'time_ms': lambda x: x * 1e3,
|
||||||
|
'time_ns': lambda x: x * 1e9,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
MeasurementType('time_us', 'microseconds', 'time',
|
MeasurementType('time_us', 'microseconds', 'time',
|
||||||
conversions={
|
conversions={
|
||||||
'time': lambda x: x / 1000000,
|
'time': lambda x: x / 1e6,
|
||||||
'time_ms': lambda x: x / 1000,
|
'time_ms': lambda x: x / 1e3,
|
||||||
|
'time_ns': lambda x: x * 1e3,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
MeasurementType('time_ms', 'milliseconds', 'time',
|
MeasurementType('time_ms', 'milliseconds', 'time',
|
||||||
conversions={
|
conversions={
|
||||||
'time': lambda x: x / 1000,
|
'time': lambda x: x / 1e3,
|
||||||
'time_us': lambda x: x * 1000,
|
'time_us': lambda x: x * 1e3,
|
||||||
|
'time_ns': lambda x: x * 1e6,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
MeasurementType('time_ns', 'nanoseconds', 'time',
|
||||||
|
conversions={
|
||||||
|
'time': lambda x: x / 1e9,
|
||||||
|
'time_ms': lambda x: x / 1e6,
|
||||||
|
'time_us': lambda x: x / 1e3,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -151,6 +161,7 @@ class Measurement(object):
|
|||||||
self.value = value
|
self.value = value
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
|
|
||||||
|
# pylint: disable=undefined-variable
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
if hasattr(other, 'value'):
|
if hasattr(other, 'value'):
|
||||||
return cmp(self.value, other.value)
|
return cmp(self.value, other.value)
|
||||||
@ -204,7 +215,7 @@ class MeasurementsCsv(object):
|
|||||||
for mt in MEASUREMENT_TYPES:
|
for mt in MEASUREMENT_TYPES:
|
||||||
suffix = '_{}'.format(mt)
|
suffix = '_{}'.format(mt)
|
||||||
if entry.endswith(suffix):
|
if entry.endswith(suffix):
|
||||||
site = entry[:-len(suffix)]
|
site = entry[:-len(suffix)]
|
||||||
measure = mt
|
measure = mt
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@ -218,6 +229,7 @@ class MeasurementsCsv(object):
|
|||||||
chan = InstrumentChannel(site, measure)
|
chan = InstrumentChannel(site, measure)
|
||||||
self.channels.append(chan)
|
self.channels.append(chan)
|
||||||
|
|
||||||
|
# pylint: disable=stop-iteration-return
|
||||||
def _iter_rows(self):
|
def _iter_rows(self):
|
||||||
with csvreader(self.path) as reader:
|
with csvreader(self.path) as reader:
|
||||||
next(reader) # headings
|
next(reader) # headings
|
||||||
@ -308,16 +320,16 @@ class Instrument(object):
|
|||||||
msg = 'Unexpected channel "{}"; must be in {}'
|
msg = 'Unexpected channel "{}"; must be in {}'
|
||||||
raise ValueError(msg.format(e, self.channels.keys()))
|
raise ValueError(msg.format(e, self.channels.keys()))
|
||||||
elif sites is None and kinds is None:
|
elif sites is None and kinds is None:
|
||||||
self.active_channels = sorted(self.channels.itervalues(), key=lambda x: x.label)
|
self.active_channels = sorted(self.channels.values(), key=lambda x: x.label)
|
||||||
else:
|
else:
|
||||||
if isinstance(sites, basestring):
|
if isinstance(sites, basestring):
|
||||||
sites = [sites]
|
sites = [sites]
|
||||||
if isinstance(kinds, basestring):
|
if isinstance(kinds, basestring):
|
||||||
kinds = [kinds]
|
kinds = [kinds]
|
||||||
|
|
||||||
wanted = lambda ch : ((kinds is None or ch.kind in kinds) and
|
wanted = lambda ch: ((kinds is None or ch.kind in kinds) and
|
||||||
(sites is None or ch.site in sites))
|
(sites is None or ch.site in sites))
|
||||||
self.active_channels = filter(wanted, self.channels.itervalues())
|
self.active_channels = list(filter(wanted, self.channels.values()))
|
||||||
|
|
||||||
# instantaneous
|
# instantaneous
|
||||||
|
|
||||||
@ -332,6 +344,7 @@ class Instrument(object):
|
|||||||
def stop(self):
|
def stop(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# pylint: disable=no-self-use
|
||||||
def get_data(self, outfile):
|
def get_data(self, outfile):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -14,14 +14,15 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
#pylint: disable=attribute-defined-outside-init
|
#pylint: disable=attribute-defined-outside-init
|
||||||
from __future__ import division
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import shlex
|
||||||
from fcntl import fcntl, F_GETFL, F_SETFL
|
from fcntl import fcntl, F_GETFL, F_SETFL
|
||||||
from string import Template
|
from string import Template
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
from shlex import quote
|
||||||
|
|
||||||
from devlib import Instrument, CONTINUOUS, MeasurementsCsv
|
from devlib import Instrument, CONTINUOUS, MeasurementsCsv
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
@ -56,12 +57,14 @@ class AcmeCapeInstrument(Instrument):
|
|||||||
iio_capture=which('iio-capture'),
|
iio_capture=which('iio-capture'),
|
||||||
host='baylibre-acme.local',
|
host='baylibre-acme.local',
|
||||||
iio_device='iio:device0',
|
iio_device='iio:device0',
|
||||||
buffer_size=256):
|
buffer_size=256,
|
||||||
|
keep_raw=False):
|
||||||
super(AcmeCapeInstrument, self).__init__(target)
|
super(AcmeCapeInstrument, self).__init__(target)
|
||||||
self.iio_capture = iio_capture
|
self.iio_capture = iio_capture
|
||||||
self.host = host
|
self.host = host
|
||||||
self.iio_device = iio_device
|
self.iio_device = iio_device
|
||||||
self.buffer_size = buffer_size
|
self.buffer_size = buffer_size
|
||||||
|
self.keep_raw = keep_raw
|
||||||
self.sample_rate_hz = 100
|
self.sample_rate_hz = 100
|
||||||
if self.iio_capture is None:
|
if self.iio_capture is None:
|
||||||
raise HostError('Missing iio-capture binary')
|
raise HostError('Missing iio-capture binary')
|
||||||
@ -85,15 +88,17 @@ class AcmeCapeInstrument(Instrument):
|
|||||||
params = dict(
|
params = dict(
|
||||||
iio_capture=self.iio_capture,
|
iio_capture=self.iio_capture,
|
||||||
host=self.host,
|
host=self.host,
|
||||||
buffer_size=self.buffer_size,
|
# This must be a string for quote()
|
||||||
|
buffer_size=str(self.buffer_size),
|
||||||
iio_device=self.iio_device,
|
iio_device=self.iio_device,
|
||||||
outfile=self.raw_data_file
|
outfile=self.raw_data_file
|
||||||
)
|
)
|
||||||
|
params = {k: quote(v) for k, v in params.items()}
|
||||||
self.command = IIOCAP_CMD_TEMPLATE.substitute(**params)
|
self.command = IIOCAP_CMD_TEMPLATE.substitute(**params)
|
||||||
self.logger.debug('ACME cape command: {}'.format(self.command))
|
self.logger.debug('ACME cape command: {}'.format(self.command))
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.process = Popen(self.command.split(), stdout=PIPE, stderr=STDOUT)
|
self.process = Popen(shlex.split(self.command), stdout=PIPE, stderr=STDOUT)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.process.terminate()
|
self.process.terminate()
|
||||||
@ -111,10 +116,7 @@ class AcmeCapeInstrument(Instrument):
|
|||||||
msg = 'Could not terminate iio-capture:\n{}'
|
msg = 'Could not terminate iio-capture:\n{}'
|
||||||
raise HostError(msg.format(output))
|
raise HostError(msg.format(output))
|
||||||
if self.process.returncode != 15: # iio-capture exits with 15 when killed
|
if self.process.returncode != 15: # iio-capture exits with 15 when killed
|
||||||
if sys.version_info[0] == 3:
|
output += self.process.stdout.read().decode(sys.stdout.encoding or 'utf-8', 'replace')
|
||||||
output += self.process.stdout.read().decode(sys.stdout.encoding, 'replace')
|
|
||||||
else:
|
|
||||||
output += self.process.stdout.read()
|
|
||||||
self.logger.info('ACME instrument encountered an error, '
|
self.logger.info('ACME instrument encountered an error, '
|
||||||
'you may want to try rebooting the ACME device:\n'
|
'you may want to try rebooting the ACME device:\n'
|
||||||
' ssh root@{} reboot'.format(self.host))
|
' ssh root@{} reboot'.format(self.host))
|
||||||
@ -155,3 +157,8 @@ class AcmeCapeInstrument(Instrument):
|
|||||||
|
|
||||||
def get_raw(self):
|
def get_raw(self):
|
||||||
return [self.raw_data_file]
|
return [self.raw_data_file]
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
if not self.keep_raw:
|
||||||
|
if os.path.isfile(self.raw_data_file):
|
||||||
|
os.remove(self.raw_data_file)
|
||||||
|
@ -30,15 +30,13 @@
|
|||||||
|
|
||||||
|
|
||||||
# pylint: disable=W0613,E1101,access-member-before-definition,attribute-defined-outside-init
|
# pylint: disable=W0613,E1101,access-member-before-definition,attribute-defined-outside-init
|
||||||
from __future__ import division
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import signal
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import tempfile
|
|
||||||
import shutil
|
import shutil
|
||||||
|
import signal
|
||||||
|
import tempfile
|
||||||
|
import subprocess
|
||||||
|
from shlex import quote
|
||||||
|
|
||||||
|
|
||||||
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
@ -72,7 +70,7 @@ class ArmEnergyProbeInstrument(Instrument):
|
|||||||
|
|
||||||
MAX_CHANNELS = 12 # 4 Arm Energy Probes
|
MAX_CHANNELS = 12 # 4 Arm Energy Probes
|
||||||
|
|
||||||
def __init__(self, target, config_file='./config-aep', ):
|
def __init__(self, target, config_file='./config-aep', keep_raw=False):
|
||||||
super(ArmEnergyProbeInstrument, self).__init__(target)
|
super(ArmEnergyProbeInstrument, self).__init__(target)
|
||||||
self.arm_probe = which('arm-probe')
|
self.arm_probe = which('arm-probe')
|
||||||
if self.arm_probe is None:
|
if self.arm_probe is None:
|
||||||
@ -81,6 +79,7 @@ class ArmEnergyProbeInstrument(Instrument):
|
|||||||
self.attributes = ['power', 'voltage', 'current']
|
self.attributes = ['power', 'voltage', 'current']
|
||||||
self.sample_rate_hz = 10000
|
self.sample_rate_hz = 10000
|
||||||
self.config_file = config_file
|
self.config_file = config_file
|
||||||
|
self.keep_raw = keep_raw
|
||||||
|
|
||||||
self.parser = AepParser()
|
self.parser = AepParser()
|
||||||
#TODO make it generic
|
#TODO make it generic
|
||||||
@ -99,7 +98,7 @@ class ArmEnergyProbeInstrument(Instrument):
|
|||||||
self.output_file_figure = os.path.join(self.output_directory, 'summary.txt')
|
self.output_file_figure = os.path.join(self.output_directory, 'summary.txt')
|
||||||
self.output_file_error = os.path.join(self.output_directory, 'error.log')
|
self.output_file_error = os.path.join(self.output_directory, 'error.log')
|
||||||
self.output_fd_error = open(self.output_file_error, 'w')
|
self.output_fd_error = open(self.output_file_error, 'w')
|
||||||
self.command = 'arm-probe --config {} > {}'.format(self.config_file, self.output_file_raw)
|
self.command = 'arm-probe --config {} > {}'.format(quote(self.config_file), quote(self.output_file_raw))
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.logger.debug(self.command)
|
self.logger.debug(self.command)
|
||||||
@ -109,8 +108,8 @@ class ArmEnergyProbeInstrument(Instrument):
|
|||||||
shell=True)
|
shell=True)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.logger.debug("kill running arm-probe")
|
self.logger.debug("kill running arm-probe")
|
||||||
os.killpg(self.armprobe.pid, signal.SIGTERM)
|
os.killpg(self.armprobe.pid, signal.SIGTERM)
|
||||||
|
|
||||||
def get_data(self, outfile): # pylint: disable=R0914
|
def get_data(self, outfile): # pylint: disable=R0914
|
||||||
self.logger.debug("Parse data and compute consumed energy")
|
self.logger.debug("Parse data and compute consumed energy")
|
||||||
@ -133,7 +132,7 @@ class ArmEnergyProbeInstrument(Instrument):
|
|||||||
if len(row) < len(active_channels):
|
if len(row) < len(active_channels):
|
||||||
continue
|
continue
|
||||||
# all data are in micro (seconds/watt)
|
# all data are in micro (seconds/watt)
|
||||||
new = [ float(row[i])/1000000 for i in active_indexes ]
|
new = [float(row[i])/1000000 for i in active_indexes]
|
||||||
writer.writerow(new)
|
writer.writerow(new)
|
||||||
|
|
||||||
self.output_fd_error.close()
|
self.output_fd_error.close()
|
||||||
@ -143,3 +142,8 @@ class ArmEnergyProbeInstrument(Instrument):
|
|||||||
|
|
||||||
def get_raw(self):
|
def get_raw(self):
|
||||||
return [self.output_file_raw]
|
return [self.output_file_raw]
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
if not self.keep_raw:
|
||||||
|
if os.path.isfile(self.output_file_raw):
|
||||||
|
os.remove(self.output_file_raw)
|
||||||
|
557
devlib/instrument/baylibre_acme.py
Normal file
557
devlib/instrument/baylibre_acme.py
Normal file
@ -0,0 +1,557 @@
|
|||||||
|
#pylint: disable=attribute-defined-outside-init
|
||||||
|
|
||||||
|
import collections
|
||||||
|
import functools
|
||||||
|
import re
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from past.builtins import basestring
|
||||||
|
|
||||||
|
try:
|
||||||
|
import iio
|
||||||
|
except ImportError as e:
|
||||||
|
iio_import_failed = True
|
||||||
|
iio_import_error = e
|
||||||
|
else:
|
||||||
|
iio_import_failed = False
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from devlib import CONTINUOUS, Instrument, HostError, MeasurementsCsv, TargetError
|
||||||
|
from devlib.utils.ssh import SshConnection
|
||||||
|
|
||||||
|
class IIOINA226Channel(object):
|
||||||
|
|
||||||
|
def __init__(self, iio_channel):
|
||||||
|
|
||||||
|
channel_id = iio_channel.id
|
||||||
|
channel_type = iio_channel.attrs['type'].value
|
||||||
|
|
||||||
|
re_measure = r'(?P<measure>\w+)(?P<index>\d*)$'
|
||||||
|
re_dtype = r'le:(?P<sign>\w)(?P<width>\d+)/(?P<size>\d+)>>(?P<align>\d+)'
|
||||||
|
|
||||||
|
match_measure = re.search(re_measure, channel_id)
|
||||||
|
match_dtype = re.search(re_dtype, channel_type)
|
||||||
|
|
||||||
|
if not match_measure:
|
||||||
|
msg = "IIO channel ID '{}' does not match expected RE '{}'"
|
||||||
|
raise ValueError(msg.format(channel_id, re_measure))
|
||||||
|
|
||||||
|
if not match_dtype:
|
||||||
|
msg = "'IIO channel type '{}' does not match expected RE '{}'"
|
||||||
|
raise ValueError(msg.format(channel_type, re_dtype))
|
||||||
|
|
||||||
|
self.measure = match_measure.group('measure')
|
||||||
|
self.iio_dtype = 'int{}'.format(match_dtype.group('width'))
|
||||||
|
self.iio_channel = iio_channel
|
||||||
|
# Data is reported in amps, volts, watts and microseconds:
|
||||||
|
self.iio_scale = (1. if 'scale' not in iio_channel.attrs
|
||||||
|
else float(iio_channel.attrs['scale'].value))
|
||||||
|
self.iio_scale /= 1000
|
||||||
|
# As calls to iio_store_buffer will be blocking and probably coming
|
||||||
|
# from a loop retrieving samples from the ACME, we want to provide
|
||||||
|
# consistency in processing timing between iterations i.e. we want
|
||||||
|
# iio_store_buffer to be o(1) for every call (can't have that with []):
|
||||||
|
self.sample_buffers = collections.deque()
|
||||||
|
|
||||||
|
def iio_store_buffer_samples(self, iio_buffer):
|
||||||
|
# IIO buffers receive and store their data as an interlaced array of
|
||||||
|
# samples from all the IIO channels of the IIO device. The IIO library
|
||||||
|
# provides a reliable function to extract the samples (bytes, actually)
|
||||||
|
# corresponding to a channel from the received buffer; in Python, it is
|
||||||
|
# iio.Channel.read(iio.Buffer).
|
||||||
|
#
|
||||||
|
# NB: As this is called in a potentially tightly timed loop, we do as
|
||||||
|
# little work as possible:
|
||||||
|
self.sample_buffers.append(self.iio_channel.read(iio_buffer))
|
||||||
|
|
||||||
|
def iio_get_samples(self, absolute_timestamps=False):
|
||||||
|
# Up to this point, the data is not interpreted yet i.e. these are
|
||||||
|
# bytearrays. Hence the use of np.dtypes.
|
||||||
|
buffers = [np.frombuffer(b, dtype=self.iio_dtype)
|
||||||
|
for b in self.sample_buffers]
|
||||||
|
|
||||||
|
must_shift = (self.measure == 'timestamp' and not absolute_timestamps)
|
||||||
|
samples = np.concatenate(buffers)
|
||||||
|
return (samples - samples[0] if must_shift else samples) * self.iio_scale
|
||||||
|
|
||||||
|
def iio_forget_samples(self):
|
||||||
|
self.sample_buffers.clear()
|
||||||
|
|
||||||
|
|
||||||
|
# Decorators for the attributes of IIOINA226Instrument:
|
||||||
|
|
||||||
|
def only_set_to(valid_values, dynamic=False):
|
||||||
|
def validating_wrapper(func):
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(self, value):
|
||||||
|
values = (valid_values if not dynamic
|
||||||
|
else getattr(self, valid_values))
|
||||||
|
if value not in values:
|
||||||
|
msg = '{} is invalid; expected values are {}'
|
||||||
|
raise ValueError(msg.format(value, valid_values))
|
||||||
|
return func(self, value)
|
||||||
|
return wrapper
|
||||||
|
return validating_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def with_input_as(wanted_type):
|
||||||
|
def typecasting_wrapper(func):
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(self, value):
|
||||||
|
return func(self, wanted_type(value))
|
||||||
|
return wrapper
|
||||||
|
return typecasting_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def _IIODeviceAttr(attr_name, attr_type, writable=False, dyn_vals=None, stat_vals=None):
|
||||||
|
|
||||||
|
def getter(self):
|
||||||
|
return attr_type(self.iio_device.attrs[attr_name].value)
|
||||||
|
|
||||||
|
def setter(self, value):
|
||||||
|
self.iio_device.attrs[attr_name].value = str(attr_type(value))
|
||||||
|
|
||||||
|
if writable and (dyn_vals or stat_vals):
|
||||||
|
vals, dyn = dyn_vals or stat_vals, dyn_vals is not None
|
||||||
|
setter = with_input_as(attr_type)(only_set_to(vals, dyn)(setter))
|
||||||
|
|
||||||
|
return property(getter, setter if writable else None)
|
||||||
|
|
||||||
|
|
||||||
|
def _IIOChannelIntTime(chan_name):
|
||||||
|
|
||||||
|
attr_name, attr_type = 'integration_time', float
|
||||||
|
|
||||||
|
def getter(self):
|
||||||
|
ch = self.iio_device.find_channel(chan_name)
|
||||||
|
return attr_type(ch.attrs[attr_name].value)
|
||||||
|
|
||||||
|
@only_set_to('INTEGRATION_TIMES_AVAILABLE', dynamic=True)
|
||||||
|
@with_input_as(attr_type)
|
||||||
|
def setter(self, value):
|
||||||
|
ch = self.iio_device.find_channel(chan_name)
|
||||||
|
ch.attrs[attr_name].value = str(value)
|
||||||
|
|
||||||
|
return property(getter, setter)
|
||||||
|
|
||||||
|
|
||||||
|
def _setify(x):
|
||||||
|
return {x} if isinstance(x, basestring) else set(x) #Py3: basestring->str
|
||||||
|
|
||||||
|
|
||||||
|
class IIOINA226Instrument(object):
|
||||||
|
|
||||||
|
IIO_DEVICE_NAME = 'ina226'
|
||||||
|
|
||||||
|
def __init__(self, iio_device):
|
||||||
|
|
||||||
|
if iio_device.name != self.IIO_DEVICE_NAME:
|
||||||
|
msg = 'IIO device is {}; expected {}'
|
||||||
|
raise TargetError(msg.format(iio_device.name, self.IIO_DEVICE_NAME))
|
||||||
|
|
||||||
|
self.iio_device = iio_device
|
||||||
|
self.absolute_timestamps = False
|
||||||
|
self.high_resolution = True
|
||||||
|
self.buffer_samples_count = None
|
||||||
|
self.buffer_is_circular = False
|
||||||
|
|
||||||
|
self.collector = None
|
||||||
|
self.work_done = threading.Event()
|
||||||
|
self.collector_exception = None
|
||||||
|
|
||||||
|
self.data = collections.OrderedDict()
|
||||||
|
|
||||||
|
channels = {
|
||||||
|
'timestamp': 'timestamp',
|
||||||
|
'shunt' : 'voltage0',
|
||||||
|
'voltage' : 'voltage1', # bus
|
||||||
|
'power' : 'power2',
|
||||||
|
'current' : 'current3',
|
||||||
|
}
|
||||||
|
self.computable_channels = {'current' : {'shunt'},
|
||||||
|
'power' : {'shunt', 'voltage'}}
|
||||||
|
self.uncomputable_channels = set(channels) - set(self.computable_channels)
|
||||||
|
self.channels = {k: IIOINA226Channel(self.iio_device.find_channel(v))
|
||||||
|
for k, v in channels.items()}
|
||||||
|
# We distinguish between "output" channels (as seen by the user of this
|
||||||
|
# class) and "hardware" channels (as requested from the INA226).
|
||||||
|
# This is necessary because of the 'high_resolution' feature which
|
||||||
|
# requires outputting computed channels:
|
||||||
|
self.active_channels = set() # "hardware" channels
|
||||||
|
self.wanted_channels = set() # "output" channels
|
||||||
|
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
|
||||||
|
OVERSAMPLING_RATIOS_AVAILABLE = (1, 4, 16, 64, 128, 256, 512, 1024)
|
||||||
|
INTEGRATION_TIMES_AVAILABLE = _IIODeviceAttr('integration_time_available',
|
||||||
|
lambda x: tuple(map(float, x.split())))
|
||||||
|
|
||||||
|
sample_rate_hz = _IIODeviceAttr('in_sampling_frequency', int)
|
||||||
|
shunt_resistor = _IIODeviceAttr('in_shunt_resistor' , int, True)
|
||||||
|
oversampling_ratio = _IIODeviceAttr('in_oversampling_ratio', int, True,
|
||||||
|
dyn_vals='OVERSAMPLING_RATIOS_AVAILABLE')
|
||||||
|
|
||||||
|
integration_time_shunt = _IIOChannelIntTime('voltage0')
|
||||||
|
integration_time_bus = _IIOChannelIntTime('voltage1')
|
||||||
|
|
||||||
|
def list_channels(self):
|
||||||
|
return self.channels.keys()
|
||||||
|
|
||||||
|
def activate(self, channels=None):
|
||||||
|
all_channels = set(self.channels)
|
||||||
|
requested_channels = (all_channels if channels is None
|
||||||
|
else _setify(channels))
|
||||||
|
|
||||||
|
unknown = ', '.join(requested_channels - all_channels)
|
||||||
|
if unknown:
|
||||||
|
raise ValueError('Unknown channel(s): {}'.format(unknown))
|
||||||
|
|
||||||
|
self.wanted_channels |= requested_channels
|
||||||
|
|
||||||
|
def deactivate(self, channels=None):
|
||||||
|
unwanted_channels = (self.wanted_channels if channels is None
|
||||||
|
else _setify(channels))
|
||||||
|
|
||||||
|
unknown = ', '.join(unwanted_channels - set(self.channels))
|
||||||
|
if unknown:
|
||||||
|
raise ValueError('Unknown channel(s): {}'.format(unknown))
|
||||||
|
|
||||||
|
unactive = ', '.join(unwanted_channels - self.wanted_channels)
|
||||||
|
if unactive:
|
||||||
|
raise ValueError('Already unactive channel(s): {}'.format(unactive))
|
||||||
|
|
||||||
|
self.wanted_channels -= unwanted_channels
|
||||||
|
|
||||||
|
def sample_collector(self):
|
||||||
|
class Collector(threading.Thread):
|
||||||
|
def run(collector_self):
|
||||||
|
for name, ch in self.channels.items():
|
||||||
|
ch.iio_channel.enabled = (name in self.active_channels)
|
||||||
|
|
||||||
|
samples_count = self.buffer_samples_count or self.sample_rate_hz
|
||||||
|
|
||||||
|
iio_buffer = iio.Buffer(self.iio_device, samples_count,
|
||||||
|
self.buffer_is_circular)
|
||||||
|
# NB: This buffer creates a communication pipe to the
|
||||||
|
# BeagleBone (or is it between the BBB and the ACME?)
|
||||||
|
# that locks down any configuration. The IIO drivers
|
||||||
|
# do not limit access when a buffer exists so that
|
||||||
|
# configuring the INA226 (i.e. accessing iio.Device.attrs
|
||||||
|
# or iio.Channel.attrs from iio.Device.channels i.e.
|
||||||
|
# assigning to or reading from any property of this class
|
||||||
|
# or calling its setup or reset methods) will screw up the
|
||||||
|
# whole system and will require rebooting the BBB-ACME board!
|
||||||
|
|
||||||
|
self.collector_exception = None
|
||||||
|
try:
|
||||||
|
refilled_once = False
|
||||||
|
while not (refilled_once and self.work_done.is_set()):
|
||||||
|
refilled_once = True
|
||||||
|
iio_buffer.refill()
|
||||||
|
for name in self.active_channels:
|
||||||
|
self.channels[name].iio_store_buffer_samples(iio_buffer)
|
||||||
|
except Exception as e:
|
||||||
|
self.collector_exception = e
|
||||||
|
finally:
|
||||||
|
del iio_buffer
|
||||||
|
for ch in self.channels.values():
|
||||||
|
ch.enabled = False
|
||||||
|
|
||||||
|
return Collector()
|
||||||
|
|
||||||
|
def start_capturing(self):
|
||||||
|
if not self.wanted_channels:
|
||||||
|
raise TargetError('No active channel: aborting.')
|
||||||
|
|
||||||
|
self.active_channels = self.wanted_channels.copy()
|
||||||
|
if self.high_resolution:
|
||||||
|
self.active_channels &= self.uncomputable_channels
|
||||||
|
for channel, dependencies in self.computable_channels.items():
|
||||||
|
if channel in self.wanted_channels:
|
||||||
|
self.active_channels |= dependencies
|
||||||
|
|
||||||
|
self.work_done.clear()
|
||||||
|
self.collector = self.sample_collector()
|
||||||
|
self.collector.daemon = True
|
||||||
|
self.collector.start()
|
||||||
|
|
||||||
|
def stop_capturing(self):
|
||||||
|
self.work_done.set()
|
||||||
|
self.collector.join()
|
||||||
|
|
||||||
|
if self.collector_exception:
|
||||||
|
raise self.collector_exception
|
||||||
|
|
||||||
|
self.data.clear()
|
||||||
|
for channel in self.active_channels:
|
||||||
|
ch = self.channels[channel]
|
||||||
|
self.data[channel] = ch.iio_get_samples(self.absolute_timestamps)
|
||||||
|
ch.iio_forget_samples()
|
||||||
|
|
||||||
|
if self.high_resolution:
|
||||||
|
res_ohm = 1e-6 * self.shunt_resistor
|
||||||
|
current = self.data['shunt'] / res_ohm
|
||||||
|
if 'current' in self.wanted_channels:
|
||||||
|
self.data['current'] = current
|
||||||
|
if 'power' in self.wanted_channels:
|
||||||
|
self.data['power'] = current * self.data['voltage']
|
||||||
|
for channel in set(self.data) - self.wanted_channels:
|
||||||
|
del self.data[channel]
|
||||||
|
|
||||||
|
self.active_channels.clear()
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
|
||||||
|
class BaylibreAcmeInstrument(Instrument):
|
||||||
|
|
||||||
|
mode = CONTINUOUS
|
||||||
|
|
||||||
|
MINIMAL_ACME_SD_IMAGE_VERSION = (2, 1, 3)
|
||||||
|
MINIMAL_ACME_IIO_DRIVERS_VERSION = (0, 6)
|
||||||
|
MINIMAL_HOST_IIO_DRIVERS_VERSION = (0, 15)
|
||||||
|
|
||||||
|
def __init__(self, target=None, iio_context=None,
|
||||||
|
use_base_iio_context=False, probe_names=None):
|
||||||
|
|
||||||
|
if iio_import_failed:
|
||||||
|
raise HostError('Could not import "iio": {}'.format(iio_import_error))
|
||||||
|
|
||||||
|
super(BaylibreAcmeInstrument, self).__init__(target)
|
||||||
|
|
||||||
|
if isinstance(probe_names, basestring):
|
||||||
|
probe_names = [probe_names]
|
||||||
|
|
||||||
|
self.iio_context = (iio_context if not use_base_iio_context
|
||||||
|
else iio.Context(iio_context))
|
||||||
|
|
||||||
|
self.check_version()
|
||||||
|
|
||||||
|
if probe_names is not None:
|
||||||
|
if len(probe_names) != len(set(probe_names)):
|
||||||
|
msg = 'Probe names should be unique: {}'
|
||||||
|
raise ValueError(msg.format(probe_names))
|
||||||
|
|
||||||
|
if len(probe_names) != len(self.iio_context.devices):
|
||||||
|
msg = ('There should be as many probe_names ({}) '
|
||||||
|
'as detected probes ({}).')
|
||||||
|
raise ValueError(msg.format(len(probe_names),
|
||||||
|
len(self.iio_context.devices)))
|
||||||
|
|
||||||
|
probes = [IIOINA226Instrument(d) for d in self.iio_context.devices]
|
||||||
|
|
||||||
|
self.probes = (dict(zip(probe_names, probes)) if probe_names
|
||||||
|
else {p.iio_device.id : p for p in probes})
|
||||||
|
self.active_probes = set()
|
||||||
|
|
||||||
|
for probe in self.probes:
|
||||||
|
for measure in ['voltage', 'power', 'current']:
|
||||||
|
self.add_channel(site=probe, measure=measure)
|
||||||
|
self.add_channel('timestamp', 'time_us')
|
||||||
|
|
||||||
|
self.data = pd.DataFrame()
|
||||||
|
|
||||||
|
def check_version(self):
|
||||||
|
msg = ('The IIO drivers running on {} ({}) are out-of-date; '
|
||||||
|
'devlib requires {} or later.')
|
||||||
|
|
||||||
|
if iio.version[:2] < self.MINIMAL_HOST_IIO_DRIVERS_VERSION:
|
||||||
|
ver_str = '.'.join(map(str, iio.version[:2]))
|
||||||
|
min_str = '.'.join(map(str, self.MINIMAL_HOST_IIO_DRIVERS_VERSION))
|
||||||
|
raise HostError(msg.format('this host', ver_str, min_str))
|
||||||
|
|
||||||
|
if self.version[:2] < self.MINIMAL_ACME_IIO_DRIVERS_VERSION:
|
||||||
|
ver_str = '.'.join(map(str, self.version[:2]))
|
||||||
|
min_str = '.'.join(map(str, self.MINIMAL_ACME_IIO_DRIVERS_VERSION))
|
||||||
|
raise TargetError(msg.format('the BBB', ver_str, min_str))
|
||||||
|
|
||||||
|
# properties
|
||||||
|
|
||||||
|
def probes_unique_property(self, property_name):
|
||||||
|
probes = self.active_probes or self.probes
|
||||||
|
try:
|
||||||
|
# This will fail if there is not exactly one single value:
|
||||||
|
(value,) = {getattr(self.probes[p], property_name) for p in probes}
|
||||||
|
except ValueError:
|
||||||
|
msg = 'Probes have different values for {}.'
|
||||||
|
raise ValueError(msg.format(property_name) if probes else 'No probe')
|
||||||
|
return value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def version(self):
|
||||||
|
return self.iio_context.version
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OVERSAMPLING_RATIOS_AVAILABLE(self):
|
||||||
|
return self.probes_unique_property('OVERSAMPLING_RATIOS_AVAILABLE')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def INTEGRATION_TIMES_AVAILABLE(self):
|
||||||
|
return self.probes_unique_property('INTEGRATION_TIMES_AVAILABLE')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sample_rate_hz(self):
|
||||||
|
return self.probes_unique_property('sample_rate_hz')
|
||||||
|
|
||||||
|
@sample_rate_hz.setter
|
||||||
|
# This setter is required for compliance with the inherited methods
|
||||||
|
def sample_rate_hz(self, value):
|
||||||
|
if value is not None:
|
||||||
|
raise AttributeError("can't set attribute")
|
||||||
|
|
||||||
|
# initialization and teardown
|
||||||
|
|
||||||
|
def setup(self, shunt_resistor,
|
||||||
|
integration_time_bus,
|
||||||
|
integration_time_shunt,
|
||||||
|
oversampling_ratio,
|
||||||
|
buffer_samples_count=None,
|
||||||
|
buffer_is_circular=False,
|
||||||
|
absolute_timestamps=False,
|
||||||
|
high_resolution=True):
|
||||||
|
|
||||||
|
def pseudo_list(v, i):
|
||||||
|
try:
|
||||||
|
return v[i]
|
||||||
|
except TypeError:
|
||||||
|
return v
|
||||||
|
|
||||||
|
for i, p in enumerate(self.probes.values()):
|
||||||
|
for attr, val in locals().items():
|
||||||
|
if attr != 'self':
|
||||||
|
setattr(p, attr, pseudo_list(val, i))
|
||||||
|
|
||||||
|
self.absolute_timestamps = all(pseudo_list(absolute_timestamps, i)
|
||||||
|
for i in range(len(self.probes)))
|
||||||
|
|
||||||
|
def reset(self, sites=None, kinds=None, channels=None):
|
||||||
|
|
||||||
|
# populate self.active_channels:
|
||||||
|
super(BaylibreAcmeInstrument, self).reset(sites, kinds, channels)
|
||||||
|
|
||||||
|
for ch in self.active_channels:
|
||||||
|
if ch.site != 'timestamp':
|
||||||
|
self.probes[ch.site].activate(['timestamp', ch.kind])
|
||||||
|
self.active_probes.add(ch.site)
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
del self.active_channels[:]
|
||||||
|
self.active_probes.clear()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
for p in self.active_probes:
|
||||||
|
self.probes[p].start_capturing()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
for p in self.active_probes:
|
||||||
|
self.probes[p].stop_capturing()
|
||||||
|
|
||||||
|
max_rate_probe = max(self.active_probes,
|
||||||
|
key=lambda p: self.probes[p].sample_rate_hz)
|
||||||
|
|
||||||
|
probes_dataframes = {
|
||||||
|
probe: pd.DataFrame.from_dict(self.probes[probe].get_data())
|
||||||
|
.set_index('timestamp')
|
||||||
|
for probe in self.active_probes
|
||||||
|
}
|
||||||
|
|
||||||
|
for df in probes_dataframes.values():
|
||||||
|
df.set_index(pd.to_datetime(df.index, unit='us'), inplace=True)
|
||||||
|
|
||||||
|
final_index = probes_dataframes[max_rate_probe].index
|
||||||
|
|
||||||
|
df = pd.concat(probes_dataframes, axis=1).sort_index()
|
||||||
|
df.columns = ['_'.join(c).strip() for c in df.columns.values]
|
||||||
|
|
||||||
|
self.data = df.interpolate('time').reindex(final_index)
|
||||||
|
|
||||||
|
if not self.absolute_timestamps:
|
||||||
|
epoch_index = self.data.index.astype(np.int64) // 1000
|
||||||
|
self.data.set_index(epoch_index, inplace=True)
|
||||||
|
# self.data.index is in [us]
|
||||||
|
# columns are in volts, amps and watts
|
||||||
|
|
||||||
|
def get_data(self, outfile=None, **to_csv_kwargs):
|
||||||
|
if outfile is None:
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
self.data.to_csv(outfile, **to_csv_kwargs)
|
||||||
|
return MeasurementsCsv(outfile, self.active_channels)
|
||||||
|
|
||||||
|
class BaylibreAcmeLocalInstrument(BaylibreAcmeInstrument):
|
||||||
|
|
||||||
|
def __init__(self, target=None, probe_names=None):
|
||||||
|
|
||||||
|
if iio_import_failed:
|
||||||
|
raise HostError('Could not import "iio": {}'.format(iio_import_error))
|
||||||
|
|
||||||
|
super(BaylibreAcmeLocalInstrument, self).__init__(
|
||||||
|
target=target,
|
||||||
|
iio_context=iio.LocalContext(),
|
||||||
|
probe_names=probe_names
|
||||||
|
)
|
||||||
|
|
||||||
|
class BaylibreAcmeXMLInstrument(BaylibreAcmeInstrument):
|
||||||
|
|
||||||
|
def __init__(self, target=None, xmlfile=None, probe_names=None):
|
||||||
|
|
||||||
|
if iio_import_failed:
|
||||||
|
raise HostError('Could not import "iio": {}'.format(iio_import_error))
|
||||||
|
|
||||||
|
super(BaylibreAcmeXMLInstrument, self).__init__(
|
||||||
|
target=target,
|
||||||
|
iio_context=iio.XMLContext(xmlfile),
|
||||||
|
probe_names=probe_names
|
||||||
|
)
|
||||||
|
|
||||||
|
class BaylibreAcmeNetworkInstrument(BaylibreAcmeInstrument):
|
||||||
|
|
||||||
|
def __init__(self, target=None, hostname=None, probe_names=None):
|
||||||
|
|
||||||
|
if iio_import_failed:
|
||||||
|
raise HostError('Could not import "iio": {}'.format(iio_import_error))
|
||||||
|
|
||||||
|
super(BaylibreAcmeNetworkInstrument, self).__init__(
|
||||||
|
target=target,
|
||||||
|
iio_context=iio.NetworkContext(hostname),
|
||||||
|
probe_names=probe_names
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.ssh_connection = SshConnection(hostname, username='root', password=None)
|
||||||
|
except TargetError as e:
|
||||||
|
msg = 'No SSH connexion could be established to {}: {}'
|
||||||
|
self.logger.debug(msg.format(hostname, e))
|
||||||
|
self.ssh_connection = None
|
||||||
|
|
||||||
|
def check_version(self):
|
||||||
|
super(BaylibreAcmeNetworkInstrument, self).check_version()
|
||||||
|
|
||||||
|
cmd = r"""sed -nr 's/^VERSION_ID="(.+)"$/\1/p' < /etc/os-release"""
|
||||||
|
try:
|
||||||
|
ver_str = self._ssh(cmd).rstrip()
|
||||||
|
ver = tuple(map(int, ver_str.split('.')))
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.debug('Unable to verify ACME SD image version through SSH: {}'.format(e))
|
||||||
|
else:
|
||||||
|
if ver < self.MINIMAL_ACME_SD_IMAGE_VERSION:
|
||||||
|
min_str = '.'.join(map(str, self.MINIMAL_ACME_SD_IMAGE_VERSION))
|
||||||
|
msg = ('The ACME SD image for the BBB (ver. {}) is out-of-date; '
|
||||||
|
'devlib requires {} or later.')
|
||||||
|
raise TargetError(msg.format(ver_str, min_str))
|
||||||
|
|
||||||
|
def _ssh(self, cmd=''):
|
||||||
|
"""Connections are assumed to be rare."""
|
||||||
|
if self.ssh_connection is None:
|
||||||
|
raise TargetError('No SSH connection; see log.')
|
||||||
|
return self.ssh_connection.execute(cmd)
|
||||||
|
|
||||||
|
def _reboot(self):
|
||||||
|
"""Always delete the object after calling its _reboot method"""
|
||||||
|
try:
|
||||||
|
self._ssh('reboot')
|
||||||
|
except:
|
||||||
|
pass
|
@ -14,20 +14,23 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
from itertools import chain
|
import time
|
||||||
|
from itertools import chain, zip_longest
|
||||||
|
|
||||||
|
from devlib.host import PACKAGE_BIN_DIRECTORY
|
||||||
from devlib.instrument import Instrument, MeasurementsCsv, CONTINUOUS
|
from devlib.instrument import Instrument, MeasurementsCsv, CONTINUOUS
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
from devlib.utils.csvutil import csvwriter, create_reader
|
from devlib.utils.csvutil import csvwriter, create_reader
|
||||||
from devlib.utils.misc import unique
|
from devlib.utils.misc import unique
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from daqpower.client import execute_command, Status
|
from daqpower.client import DaqClient
|
||||||
from daqpower.config import DeviceConfiguration, ServerConfiguration
|
from daqpower.config import DeviceConfiguration
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
execute_command, Status = None, None
|
DaqClient = None
|
||||||
DeviceConfiguration, ServerConfiguration, ConfigurationError = None, None, None
|
DeviceConfiguration = None
|
||||||
import_error_mesg = e.args[0] if e.args else str(e)
|
import_error_mesg = e.args[0] if e.args else str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -44,25 +47,30 @@ class DaqInstrument(Instrument):
|
|||||||
dv_range=0.2,
|
dv_range=0.2,
|
||||||
sample_rate_hz=10000,
|
sample_rate_hz=10000,
|
||||||
channel_map=(0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23),
|
channel_map=(0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23),
|
||||||
|
keep_raw=False,
|
||||||
|
time_as_clock_boottime=True
|
||||||
):
|
):
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
super(DaqInstrument, self).__init__(target)
|
super(DaqInstrument, self).__init__(target)
|
||||||
|
self.keep_raw = keep_raw
|
||||||
self._need_reset = True
|
self._need_reset = True
|
||||||
self._raw_files = []
|
self._raw_files = []
|
||||||
if execute_command is None:
|
self.tempdir = None
|
||||||
|
self.target_boottime_clock_at_start = 0.0
|
||||||
|
if DaqClient is None:
|
||||||
raise HostError('Could not import "daqpower": {}'.format(import_error_mesg))
|
raise HostError('Could not import "daqpower": {}'.format(import_error_mesg))
|
||||||
if labels is None:
|
if labels is None:
|
||||||
labels = ['PORT_{}'.format(i) for i in range(len(resistor_values))]
|
labels = ['PORT_{}'.format(i) for i in range(len(resistor_values))]
|
||||||
if len(labels) != len(resistor_values):
|
if len(labels) != len(resistor_values):
|
||||||
raise ValueError('"labels" and "resistor_values" must be of the same length')
|
raise ValueError('"labels" and "resistor_values" must be of the same length')
|
||||||
self.server_config = ServerConfiguration(host=host,
|
self.daq_client = DaqClient(host, port)
|
||||||
port=port)
|
try:
|
||||||
result = self.execute('list_devices')
|
devices = self.daq_client.list_devices()
|
||||||
if result.status == Status.OK:
|
if device_id not in devices:
|
||||||
if device_id not in result.data:
|
msg = 'Device "{}" is not found on the DAQ server. Available devices are: "{}"'
|
||||||
raise ValueError('Device "{}" is not found on the DAQ server.'.format(device_id))
|
raise ValueError(msg.format(device_id, ', '.join(devices)))
|
||||||
elif result.status != Status.OKISH:
|
except Exception as e:
|
||||||
raise HostError('Problem querying DAQ server: {}'.format(result.message))
|
raise HostError('Problem querying DAQ server: {}'.format(e))
|
||||||
|
|
||||||
self.device_config = DeviceConfiguration(device_id=device_id,
|
self.device_config = DeviceConfiguration(device_id=device_id,
|
||||||
v_range=v_range,
|
v_range=v_range,
|
||||||
@ -72,36 +80,63 @@ class DaqInstrument(Instrument):
|
|||||||
channel_map=channel_map,
|
channel_map=channel_map,
|
||||||
labels=labels)
|
labels=labels)
|
||||||
self.sample_rate_hz = sample_rate_hz
|
self.sample_rate_hz = sample_rate_hz
|
||||||
|
self.time_as_clock_boottime = time_as_clock_boottime
|
||||||
|
|
||||||
|
self.add_channel('Time', 'time')
|
||||||
for label in labels:
|
for label in labels:
|
||||||
for kind in ['power', 'voltage']:
|
for kind in ['power', 'voltage']:
|
||||||
self.add_channel(label, kind)
|
self.add_channel(label, kind)
|
||||||
|
|
||||||
|
if time_as_clock_boottime:
|
||||||
|
host_path = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi,
|
||||||
|
'get_clock_boottime')
|
||||||
|
self.clock_boottime_cmd = self.target.install_if_needed(host_path,
|
||||||
|
search_system_binaries=False)
|
||||||
|
|
||||||
|
def calculate_boottime_offset(self):
|
||||||
|
time_before = time.time()
|
||||||
|
out = self.target.execute(self.clock_boottime_cmd)
|
||||||
|
time_after = time.time()
|
||||||
|
|
||||||
|
remote_clock_boottime = float(out)
|
||||||
|
propagation_delay = (time_after - time_before) / 2
|
||||||
|
boottime_at_end = remote_clock_boottime + propagation_delay
|
||||||
|
|
||||||
|
return time_after - boottime_at_end
|
||||||
|
|
||||||
def reset(self, sites=None, kinds=None, channels=None):
|
def reset(self, sites=None, kinds=None, channels=None):
|
||||||
super(DaqInstrument, self).reset(sites, kinds, channels)
|
super(DaqInstrument, self).reset(sites, kinds, channels)
|
||||||
self.execute('close')
|
self.daq_client.close()
|
||||||
result = self.execute('configure', config=self.device_config)
|
self.daq_client.configure(self.device_config)
|
||||||
if not result.status == Status.OK: # pylint: disable=no-member
|
|
||||||
raise HostError(result.message)
|
|
||||||
self._need_reset = False
|
self._need_reset = False
|
||||||
self._raw_files = []
|
self._raw_files = []
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self._need_reset:
|
if self._need_reset:
|
||||||
self.reset()
|
# Preserve channel order
|
||||||
self.execute('start')
|
self.reset(channels=self.channels.keys())
|
||||||
|
|
||||||
|
if self.time_as_clock_boottime:
|
||||||
|
target_boottime_offset = self.calculate_boottime_offset()
|
||||||
|
time_start = time.time()
|
||||||
|
|
||||||
|
self.daq_client.start()
|
||||||
|
|
||||||
|
if self.time_as_clock_boottime:
|
||||||
|
time_end = time.time()
|
||||||
|
self.target_boottime_clock_at_start = (time_start + time_end) / 2 - target_boottime_offset
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.execute('stop')
|
self.daq_client.stop()
|
||||||
self._need_reset = True
|
self._need_reset = True
|
||||||
|
|
||||||
def get_data(self, outfile): # pylint: disable=R0914
|
def get_data(self, outfile): # pylint: disable=R0914
|
||||||
tempdir = tempfile.mkdtemp(prefix='daq-raw-')
|
self.tempdir = tempfile.mkdtemp(prefix='daq-raw-')
|
||||||
self.execute('get_data', output_directory=tempdir)
|
self.daq_client.get_data(self.tempdir)
|
||||||
raw_file_map = {}
|
raw_file_map = {}
|
||||||
for entry in os.listdir(tempdir):
|
for entry in os.listdir(self.tempdir):
|
||||||
site = os.path.splitext(entry)[0]
|
site = os.path.splitext(entry)[0]
|
||||||
path = os.path.join(tempdir, entry)
|
path = os.path.join(self.tempdir, entry)
|
||||||
raw_file_map[site] = path
|
raw_file_map[site] = path
|
||||||
self._raw_files.append(path)
|
self._raw_files.append(path)
|
||||||
|
|
||||||
@ -116,32 +151,32 @@ class DaqInstrument(Instrument):
|
|||||||
site_readers[site] = reader
|
site_readers[site] = reader
|
||||||
file_handles.append(fh)
|
file_handles.append(fh)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
message = 'Could not get DAQ trace for {}; Obtained traces are in {}'
|
if not site.startswith("Time"):
|
||||||
raise HostError(message.format(site, tempdir))
|
message = 'Could not get DAQ trace for {}; Obtained traces are in {}'
|
||||||
|
raise HostError(message.format(site, self.tempdir))
|
||||||
|
|
||||||
# The first row is the headers
|
# The first row is the headers
|
||||||
channel_order = []
|
channel_order = ['Time_time']
|
||||||
for site, reader in site_readers.items():
|
for site, reader in site_readers.items():
|
||||||
channel_order.extend(['{}_{}'.format(site, kind)
|
channel_order.extend(['{}_{}'.format(site, kind)
|
||||||
for kind in next(reader)])
|
for kind in next(reader)])
|
||||||
|
|
||||||
def _read_next_rows():
|
def _read_rows():
|
||||||
parts = []
|
row_iter = zip_longest(*site_readers.values(), fillvalue=(None, None))
|
||||||
for reader in site_readers.values():
|
for raw_row in row_iter:
|
||||||
try:
|
raw_row = list(chain.from_iterable(raw_row))
|
||||||
parts.extend(next(reader))
|
raw_row.insert(0, _read_rows.row_time_s)
|
||||||
except StopIteration:
|
yield raw_row
|
||||||
parts.extend([None, None])
|
_read_rows.row_time_s += 1.0 / self.sample_rate_hz
|
||||||
return list(chain(parts))
|
|
||||||
|
_read_rows.row_time_s = self.target_boottime_clock_at_start
|
||||||
|
|
||||||
with csvwriter(outfile) as writer:
|
with csvwriter(outfile) as writer:
|
||||||
field_names = [c.label for c in self.active_channels]
|
field_names = [c.label for c in self.active_channels]
|
||||||
writer.writerow(field_names)
|
writer.writerow(field_names)
|
||||||
raw_row = _read_next_rows()
|
for raw_row in _read_rows():
|
||||||
while any(raw_row):
|
|
||||||
row = [raw_row[channel_order.index(f)] for f in field_names]
|
row = [raw_row[channel_order.index(f)] for f in field_names]
|
||||||
writer.writerow(row)
|
writer.writerow(row)
|
||||||
raw_row = _read_next_rows()
|
|
||||||
|
|
||||||
return MeasurementsCsv(outfile, self.active_channels, self.sample_rate_hz)
|
return MeasurementsCsv(outfile, self.active_channels, self.sample_rate_hz)
|
||||||
finally:
|
finally:
|
||||||
@ -152,8 +187,7 @@ class DaqInstrument(Instrument):
|
|||||||
return self._raw_files
|
return self._raw_files
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
self.execute('close')
|
self.daq_client.close()
|
||||||
|
if not self.keep_raw:
|
||||||
def execute(self, command, **kwargs):
|
if self.tempdir and os.path.isdir(self.tempdir):
|
||||||
return execute_command(self.server_config, command, **kwargs)
|
shutil.rmtree(self.tempdir)
|
||||||
|
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from __future__ import division
|
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import tempfile
|
import tempfile
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from shlex import quote
|
||||||
|
|
||||||
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
@ -33,9 +33,11 @@ class EnergyProbeInstrument(Instrument):
|
|||||||
def __init__(self, target, resistor_values,
|
def __init__(self, target, resistor_values,
|
||||||
labels=None,
|
labels=None,
|
||||||
device_entry='/dev/ttyACM0',
|
device_entry='/dev/ttyACM0',
|
||||||
|
keep_raw=False
|
||||||
):
|
):
|
||||||
super(EnergyProbeInstrument, self).__init__(target)
|
super(EnergyProbeInstrument, self).__init__(target)
|
||||||
self.resistor_values = resistor_values
|
self.resistor_values = resistor_values
|
||||||
|
self.keep_raw = keep_raw
|
||||||
if labels is not None:
|
if labels is not None:
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
else:
|
else:
|
||||||
@ -65,7 +67,10 @@ class EnergyProbeInstrument(Instrument):
|
|||||||
parts = ['-r {}:{} '.format(i, int(1000 * rval))
|
parts = ['-r {}:{} '.format(i, int(1000 * rval))
|
||||||
for i, rval in enumerate(self.resistor_values)]
|
for i, rval in enumerate(self.resistor_values)]
|
||||||
rstring = ''.join(parts)
|
rstring = ''.join(parts)
|
||||||
self.command = '{} -d {} -l {} {}'.format(self.caiman, self.device_entry, rstring, self.raw_output_directory)
|
self.command = '{} -d {} -l {} {}'.format(
|
||||||
|
quote(self.caiman), quote(self.device_entry),
|
||||||
|
rstring, quote(self.raw_output_directory)
|
||||||
|
)
|
||||||
self.raw_data_file = None
|
self.raw_data_file = None
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
@ -81,9 +86,8 @@ class EnergyProbeInstrument(Instrument):
|
|||||||
self.process.poll()
|
self.process.poll()
|
||||||
if self.process.returncode is not None:
|
if self.process.returncode is not None:
|
||||||
stdout, stderr = self.process.communicate()
|
stdout, stderr = self.process.communicate()
|
||||||
if sys.version_info[0] == 3:
|
stdout = stdout.decode(sys.stdout.encoding or 'utf-8', 'replace')
|
||||||
stdout = stdout.decode(sys.stdout.encoding, 'replace')
|
stderr = stderr.decode(sys.stdout.encoding or 'utf-8', 'replace')
|
||||||
stderr = stderr.decode(sys.stdout.encoding, 'replace')
|
|
||||||
raise HostError(
|
raise HostError(
|
||||||
'Energy Probe: Caiman exited unexpectedly with exit code {}.\n'
|
'Energy Probe: Caiman exited unexpectedly with exit code {}.\n'
|
||||||
'stdout:\n{}\nstderr:\n{}'.format(self.process.returncode,
|
'stdout:\n{}\nstderr:\n{}'.format(self.process.returncode,
|
||||||
@ -114,7 +118,7 @@ class EnergyProbeInstrument(Instrument):
|
|||||||
writer.writerow(row)
|
writer.writerow(row)
|
||||||
except struct.error:
|
except struct.error:
|
||||||
if not_a_full_row_seen:
|
if not_a_full_row_seen:
|
||||||
self.logger.warn('possibly missaligned caiman raw data, row contained {} bytes'.format(len(data)))
|
self.logger.warning('possibly missaligned caiman raw data, row contained {} bytes'.format(len(data)))
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
not_a_full_row_seen = True
|
not_a_full_row_seen = True
|
||||||
@ -122,3 +126,8 @@ class EnergyProbeInstrument(Instrument):
|
|||||||
|
|
||||||
def get_raw(self):
|
def get_raw(self):
|
||||||
return [self.raw_data_file]
|
return [self.raw_data_file]
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
if self.keep_raw:
|
||||||
|
if os.path.isfile(self.raw_data_file):
|
||||||
|
os.remove(self.raw_data_file)
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
from __future__ import division
|
import os
|
||||||
|
|
||||||
from devlib.instrument import (Instrument, CONTINUOUS,
|
from devlib.instrument import (Instrument, CONTINUOUS,
|
||||||
MeasurementsCsv, MeasurementType)
|
MeasurementsCsv, MeasurementType)
|
||||||
from devlib.utils.rendering import (GfxinfoFrameCollector,
|
from devlib.utils.rendering import (GfxinfoFrameCollector,
|
||||||
@ -41,6 +42,7 @@ class FramesInstrument(Instrument):
|
|||||||
|
|
||||||
def reset(self, sites=None, kinds=None, channels=None):
|
def reset(self, sites=None, kinds=None, channels=None):
|
||||||
super(FramesInstrument, self).reset(sites, kinds, channels)
|
super(FramesInstrument, self).reset(sites, kinds, channels)
|
||||||
|
# pylint: disable=not-callable
|
||||||
self.collector = self.collector_cls(self.target, self.period,
|
self.collector = self.collector_cls(self.target, self.period,
|
||||||
self.collector_target, self.header)
|
self.collector_target, self.header)
|
||||||
self._need_reset = False
|
self._need_reset = False
|
||||||
@ -69,6 +71,11 @@ class FramesInstrument(Instrument):
|
|||||||
def _init_channels(self):
|
def _init_channels(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
if not self.keep_raw:
|
||||||
|
if os.path.isfile(self._raw_file):
|
||||||
|
os.remove(self._raw_file)
|
||||||
|
|
||||||
|
|
||||||
class GfxInfoFramesInstrument(FramesInstrument):
|
class GfxInfoFramesInstrument(FramesInstrument):
|
||||||
|
|
||||||
@ -81,7 +88,7 @@ class GfxInfoFramesInstrument(FramesInstrument):
|
|||||||
if entry == 'Flags':
|
if entry == 'Flags':
|
||||||
self.add_channel('Flags', MeasurementType('flags', 'flags'))
|
self.add_channel('Flags', MeasurementType('flags', 'flags'))
|
||||||
else:
|
else:
|
||||||
self.add_channel(entry, 'time_us')
|
self.add_channel(entry, 'time_ns')
|
||||||
self.header = [chan.label for chan in self.channels.values()]
|
self.header = [chan.label for chan in self.channels.values()]
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,12 +12,9 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
import re
|
|
||||||
|
|
||||||
from devlib.platform.gem5 import Gem5SimulationPlatform
|
from devlib.platform.gem5 import Gem5SimulationPlatform
|
||||||
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
||||||
from devlib.exception import TargetError, HostError
|
from devlib.exception import TargetStableError
|
||||||
from devlib.utils.csvutil import csvwriter
|
from devlib.utils.csvutil import csvwriter
|
||||||
|
|
||||||
|
|
||||||
@ -37,9 +34,9 @@ class Gem5PowerInstrument(Instrument):
|
|||||||
system.cluster0.cores0.power_model.static_power
|
system.cluster0.cores0.power_model.static_power
|
||||||
'''
|
'''
|
||||||
if not isinstance(target.platform, Gem5SimulationPlatform):
|
if not isinstance(target.platform, Gem5SimulationPlatform):
|
||||||
raise TargetError('Gem5PowerInstrument requires a gem5 platform')
|
raise TargetStableError('Gem5PowerInstrument requires a gem5 platform')
|
||||||
if not target.has('gem5stats'):
|
if not target.has('gem5stats'):
|
||||||
raise TargetError('Gem5StatsModule is not loaded')
|
raise TargetStableError('Gem5StatsModule is not loaded')
|
||||||
super(Gem5PowerInstrument, self).__init__(target)
|
super(Gem5PowerInstrument, self).__init__(target)
|
||||||
|
|
||||||
# power_sites is assumed to be a list later
|
# power_sites is assumed to be a list later
|
||||||
@ -69,7 +66,7 @@ class Gem5PowerInstrument(Instrument):
|
|||||||
with csvwriter(outfile) as writer:
|
with csvwriter(outfile) as writer:
|
||||||
writer.writerow([c.label for c in self.active_channels]) # headers
|
writer.writerow([c.label for c in self.active_channels]) # headers
|
||||||
sites_to_match = [self.site_mapping.get(s, s) for s in active_sites]
|
sites_to_match = [self.site_mapping.get(s, s) for s in active_sites]
|
||||||
for rec, rois in self.target.gem5stats.match_iter(sites_to_match,
|
for rec, _ in self.target.gem5stats.match_iter(sites_to_match,
|
||||||
[self.roi_label], self._base_stats_dump):
|
[self.roi_label], self._base_stats_dump):
|
||||||
writer.writerow([rec[s] for s in sites_to_match])
|
writer.writerow([rec[s] for s in sites_to_match])
|
||||||
return MeasurementsCsv(outfile, self.active_channels, self.sample_rate_hz)
|
return MeasurementsCsv(outfile, self.active_channels, self.sample_rate_hz)
|
||||||
@ -77,4 +74,3 @@ class Gem5PowerInstrument(Instrument):
|
|||||||
def reset(self, sites=None, kinds=None, channels=None):
|
def reset(self, sites=None, kinds=None, channels=None):
|
||||||
super(Gem5PowerInstrument, self).reset(sites, kinds, channels)
|
super(Gem5PowerInstrument, self).reset(sites, kinds, channels)
|
||||||
self._base_stats_dump = self.target.gem5stats.next_dump_no()
|
self._base_stats_dump = self.target.gem5stats.next_dump_no()
|
||||||
|
|
||||||
|
@ -12,11 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from __future__ import division
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from devlib.instrument import Instrument, Measurement, INSTANTANEOUS
|
from devlib.instrument import Instrument, Measurement, INSTANTANEOUS
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import TargetStableError
|
||||||
|
|
||||||
|
|
||||||
class HwmonInstrument(Instrument):
|
class HwmonInstrument(Instrument):
|
||||||
@ -35,7 +34,7 @@ class HwmonInstrument(Instrument):
|
|||||||
|
|
||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
if not hasattr(target, 'hwmon'):
|
if not hasattr(target, 'hwmon'):
|
||||||
raise TargetError('Target does not support HWMON')
|
raise TargetStableError('Target does not support HWMON')
|
||||||
super(HwmonInstrument, self).__init__(target)
|
super(HwmonInstrument, self).__init__(target)
|
||||||
|
|
||||||
self.logger.debug('Discovering available HWMON sensors...')
|
self.logger.debug('Discovering available HWMON sensors...')
|
||||||
|
@ -21,12 +21,11 @@ from tempfile import NamedTemporaryFile
|
|||||||
|
|
||||||
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
from devlib.host import PACKAGE_BIN_DIRECTORY
|
|
||||||
from devlib.utils.csvutil import csvwriter
|
from devlib.utils.csvutil import csvwriter
|
||||||
from devlib.utils.misc import which
|
from devlib.utils.misc import which
|
||||||
|
|
||||||
|
|
||||||
INSTALL_INSTRUCTIONS="""
|
INSTALL_INSTRUCTIONS = """
|
||||||
MonsoonInstrument requires the monsoon.py tool, available from AOSP:
|
MonsoonInstrument requires the monsoon.py tool, available from AOSP:
|
||||||
|
|
||||||
https://android.googlesource.com/platform/cts/+/master/tools/utils/monsoon.py
|
https://android.googlesource.com/platform/cts/+/master/tools/utils/monsoon.py
|
||||||
@ -68,6 +67,7 @@ class MonsoonInstrument(Instrument):
|
|||||||
|
|
||||||
self.process = None
|
self.process = None
|
||||||
self.output = None
|
self.output = None
|
||||||
|
self.buffer_file = None
|
||||||
|
|
||||||
self.sample_rate_hz = 500
|
self.sample_rate_hz = 500
|
||||||
self.add_channel('output', 'power')
|
self.add_channel('output', 'power')
|
||||||
@ -100,9 +100,8 @@ class MonsoonInstrument(Instrument):
|
|||||||
process.poll()
|
process.poll()
|
||||||
if process.returncode is not None:
|
if process.returncode is not None:
|
||||||
stdout, stderr = process.communicate()
|
stdout, stderr = process.communicate()
|
||||||
if sys.version_info[0] == 3:
|
stdout = stdout.encode(sys.stdout.encoding or 'utf-8')
|
||||||
stdout = stdout.encode(sys.stdout.encoding)
|
stderr = stderr.encode(sys.stdout.encoding or 'utf-8')
|
||||||
stderr = stderr.encode(sys.stdout.encoding)
|
|
||||||
raise HostError(
|
raise HostError(
|
||||||
'Monsoon script exited unexpectedly with exit code {}.\n'
|
'Monsoon script exited unexpectedly with exit code {}.\n'
|
||||||
'stdout:\n{}\nstderr:\n{}'.format(process.returncode,
|
'stdout:\n{}\nstderr:\n{}'.format(process.returncode,
|
||||||
@ -110,7 +109,7 @@ class MonsoonInstrument(Instrument):
|
|||||||
|
|
||||||
process.send_signal(signal.SIGINT)
|
process.send_signal(signal.SIGINT)
|
||||||
|
|
||||||
stderr = process.stderr.read()
|
stderr = process.stderr.read()
|
||||||
|
|
||||||
self.buffer_file.close()
|
self.buffer_file.close()
|
||||||
with open(self.buffer_file.name) as f:
|
with open(self.buffer_file.name) as f:
|
||||||
@ -124,7 +123,7 @@ class MonsoonInstrument(Instrument):
|
|||||||
if self.process:
|
if self.process:
|
||||||
raise RuntimeError('`get_data` called before `stop`')
|
raise RuntimeError('`get_data` called before `stop`')
|
||||||
|
|
||||||
stdout, stderr = self.output
|
stdout, _ = self.output
|
||||||
|
|
||||||
with csvwriter(outfile) as writer:
|
with csvwriter(outfile) as writer:
|
||||||
active_sites = [c.site for c in self.active_channels]
|
active_sites = [c.site for c in self.active_channels]
|
||||||
|
@ -18,11 +18,10 @@ import re
|
|||||||
import tempfile
|
import tempfile
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from itertools import zip_longest
|
||||||
from future.moves.itertools import zip_longest
|
|
||||||
|
|
||||||
from devlib.instrument import Instrument, MeasurementsCsv, CONTINUOUS
|
from devlib.instrument import Instrument, MeasurementsCsv, CONTINUOUS
|
||||||
from devlib.exception import TargetError, HostError
|
from devlib.exception import TargetStableError, HostError
|
||||||
from devlib.utils.android import ApkInfo
|
from devlib.utils.android import ApkInfo
|
||||||
from devlib.utils.csvutil import csvwriter
|
from devlib.utils.csvutil import csvwriter
|
||||||
|
|
||||||
@ -84,7 +83,7 @@ class NetstatsInstrument(Instrument):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if target.os != 'android':
|
if target.os != 'android':
|
||||||
raise TargetError('netstats insturment only supports Android targets')
|
raise TargetStableError('netstats instrument only supports Android targets')
|
||||||
if apk is None:
|
if apk is None:
|
||||||
apk = os.path.join(THIS_DIR, 'netstats.apk')
|
apk = os.path.join(THIS_DIR, 'netstats.apk')
|
||||||
if not os.path.isfile(apk):
|
if not os.path.isfile(apk):
|
||||||
@ -101,6 +100,7 @@ class NetstatsInstrument(Instrument):
|
|||||||
self.add_channel(package, 'tx')
|
self.add_channel(package, 'tx')
|
||||||
self.add_channel(package, 'rx')
|
self.add_channel(package, 'rx')
|
||||||
|
|
||||||
|
# pylint: disable=keyword-arg-before-vararg,arguments-differ
|
||||||
def setup(self, force=False, *args, **kwargs):
|
def setup(self, force=False, *args, **kwargs):
|
||||||
if self.target.package_is_installed(self.package):
|
if self.target.package_is_installed(self.package):
|
||||||
if force:
|
if force:
|
||||||
|
@ -15,16 +15,30 @@
|
|||||||
import logging
|
import logging
|
||||||
from inspect import isclass
|
from inspect import isclass
|
||||||
|
|
||||||
from past.builtins import basestring
|
from devlib.exception import TargetStableError
|
||||||
|
|
||||||
from devlib.utils.misc import walk_modules
|
|
||||||
from devlib.utils.types import identifier
|
from devlib.utils.types import identifier
|
||||||
|
from devlib.utils.misc import walk_modules
|
||||||
|
|
||||||
|
_module_registry = {}
|
||||||
|
|
||||||
|
def register_module(mod):
|
||||||
|
if not issubclass(mod, Module):
|
||||||
|
raise ValueError('A module must subclass devlib.Module')
|
||||||
|
|
||||||
|
if mod.name is None:
|
||||||
|
raise ValueError('A module must define a name')
|
||||||
|
|
||||||
|
try:
|
||||||
|
existing = _module_registry[mod.name]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if existing is not mod:
|
||||||
|
raise ValueError(f'Module "{mod.name}" already exists')
|
||||||
|
_module_registry[mod.name] = mod
|
||||||
|
|
||||||
|
|
||||||
__module_cache = {}
|
class Module:
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
|
||||||
|
|
||||||
name = None
|
name = None
|
||||||
kind = None
|
kind = None
|
||||||
@ -37,6 +51,9 @@ class Module(object):
|
|||||||
# serial).
|
# serial).
|
||||||
# 'connected' -- installed when a connection to to the target has been
|
# 'connected' -- installed when a connection to to the target has been
|
||||||
# established. This is the default.
|
# established. This is the default.
|
||||||
|
# 'setup' -- installed after initial setup of the device has been performed.
|
||||||
|
# This allows the module to utilize assets deployed during the
|
||||||
|
# setup stage for example 'Busybox'.
|
||||||
stage = 'connected'
|
stage = 'connected'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -45,23 +62,49 @@ class Module(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def install(cls, target, **params):
|
def install(cls, target, **params):
|
||||||
if cls.kind is not None:
|
attr_name = cls.attr_name
|
||||||
attr_name = identifier(cls.kind)
|
installed = target._installed_modules
|
||||||
|
|
||||||
|
try:
|
||||||
|
mod = installed[attr_name]
|
||||||
|
except KeyError:
|
||||||
|
mod = cls(target, **params)
|
||||||
|
mod.logger.debug(f'Installing module {cls.name}')
|
||||||
|
|
||||||
|
if mod.probe(target):
|
||||||
|
for name in (
|
||||||
|
attr_name,
|
||||||
|
identifier(cls.name),
|
||||||
|
identifier(cls.kind) if cls.kind else None,
|
||||||
|
):
|
||||||
|
if name is not None:
|
||||||
|
installed[name] = mod
|
||||||
|
|
||||||
|
target._modules[cls.name] = params
|
||||||
|
return mod
|
||||||
|
else:
|
||||||
|
raise TargetStableError(f'Module "{cls.name}" is not supported by the target')
|
||||||
else:
|
else:
|
||||||
attr_name = identifier(cls.name)
|
raise ValueError(
|
||||||
if hasattr(target, attr_name):
|
f'Attempting to install module "{cls.name}" but a module is already installed as attribute "{attr_name}": {mod}'
|
||||||
existing_module = getattr(target, attr_name)
|
)
|
||||||
existing_name = getattr(existing_module, 'name', str(existing_module))
|
|
||||||
message = 'Attempting to install module "{}" which already exists (new: {}, existing: {})'
|
|
||||||
raise ValueError(message.format(attr_name, cls.name, existing_name))
|
|
||||||
setattr(target, attr_name, cls(target, **params))
|
|
||||||
|
|
||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
self.target = target
|
self.target = target
|
||||||
self.logger = logging.getLogger(self.name)
|
self.logger = logging.getLogger(self.name)
|
||||||
|
|
||||||
|
|
||||||
class HardRestModule(Module): # pylint: disable=R0921
|
def __init_subclass__(cls, *args, **kwargs):
|
||||||
|
super().__init_subclass__(*args, **kwargs)
|
||||||
|
|
||||||
|
attr_name = cls.kind or cls.name
|
||||||
|
cls.attr_name = identifier(attr_name) if attr_name else None
|
||||||
|
|
||||||
|
if cls.name is not None:
|
||||||
|
register_module(cls)
|
||||||
|
|
||||||
|
|
||||||
|
class HardRestModule(Module):
|
||||||
|
|
||||||
kind = 'hard_reset'
|
kind = 'hard_reset'
|
||||||
|
|
||||||
@ -69,7 +112,7 @@ class HardRestModule(Module): # pylint: disable=R0921
|
|||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class BootModule(Module): # pylint: disable=R0921
|
class BootModule(Module):
|
||||||
|
|
||||||
kind = 'boot'
|
kind = 'boot'
|
||||||
|
|
||||||
@ -88,37 +131,30 @@ class FlashModule(Module):
|
|||||||
|
|
||||||
kind = 'flash'
|
kind = 'flash'
|
||||||
|
|
||||||
def __call__(self, image_bundle=None, images=None, boot_config=None):
|
def __call__(self, image_bundle=None, images=None, boot_config=None, connect=True):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
def get_module(mod):
|
def get_module(mod):
|
||||||
if not __module_cache:
|
def from_registry(mod):
|
||||||
__load_cache()
|
|
||||||
|
|
||||||
if isinstance(mod, basestring):
|
|
||||||
try:
|
try:
|
||||||
return __module_cache[mod]
|
return _module_registry[mod]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ValueError('Module "{}" does not exist'.format(mod))
|
raise ValueError('Module "{}" does not exist'.format(mod))
|
||||||
|
|
||||||
|
if isinstance(mod, str):
|
||||||
|
try:
|
||||||
|
return from_registry(mod)
|
||||||
|
except ValueError:
|
||||||
|
# If the lookup failed, we may have simply not imported Modules
|
||||||
|
# from the devlib.module package. The former module loading
|
||||||
|
# implementation was also pre-importing modules, so we need to
|
||||||
|
# replicate that behavior since users are currently not expected to
|
||||||
|
# have imported the module prior to trying to use it.
|
||||||
|
walk_modules('devlib.module')
|
||||||
|
return from_registry(mod)
|
||||||
|
|
||||||
elif issubclass(mod, Module):
|
elif issubclass(mod, Module):
|
||||||
return mod
|
return mod
|
||||||
else:
|
else:
|
||||||
raise ValueError('Not a valid module: {}'.format(mod))
|
raise ValueError('Not a valid module: {}'.format(mod))
|
||||||
|
|
||||||
|
|
||||||
def register_module(mod):
|
|
||||||
if not issubclass(mod, Module):
|
|
||||||
raise ValueError('A module must subclass devlib.Module')
|
|
||||||
if mod.name is None:
|
|
||||||
raise ValueError('A module must define a name')
|
|
||||||
if mod.name in __module_cache:
|
|
||||||
raise ValueError('Module {} already exists'.format(mod.name))
|
|
||||||
__module_cache[mod.name] = mod
|
|
||||||
|
|
||||||
|
|
||||||
def __load_cache():
|
|
||||||
for module in walk_modules('devlib.module'):
|
|
||||||
for obj in vars(module).values():
|
|
||||||
if isclass(obj) and issubclass(obj, Module) and obj.name:
|
|
||||||
register_module(obj)
|
|
||||||
|
@ -22,7 +22,7 @@ import tempfile
|
|||||||
from devlib.module import FlashModule
|
from devlib.module import FlashModule
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
from devlib.utils.android import fastboot_flash_partition, fastboot_command
|
from devlib.utils.android import fastboot_flash_partition, fastboot_command
|
||||||
from devlib.utils.misc import merge_dicts
|
from devlib.utils.misc import merge_dicts, safe_extract
|
||||||
|
|
||||||
|
|
||||||
class FastbootFlashModule(FlashModule):
|
class FastbootFlashModule(FlashModule):
|
||||||
@ -54,7 +54,7 @@ class FastbootFlashModule(FlashModule):
|
|||||||
def probe(target):
|
def probe(target):
|
||||||
return target.os == 'android'
|
return target.os == 'android'
|
||||||
|
|
||||||
def __call__(self, image_bundle=None, images=None, bootargs=None):
|
def __call__(self, image_bundle=None, images=None, bootargs=None, connect=True):
|
||||||
if bootargs:
|
if bootargs:
|
||||||
raise ValueError('{} does not support boot configuration'.format(self.name))
|
raise ValueError('{} does not support boot configuration'.format(self.name))
|
||||||
self.prelude_done = False
|
self.prelude_done = False
|
||||||
@ -67,7 +67,8 @@ class FastbootFlashModule(FlashModule):
|
|||||||
self.logger.debug('flashing {}'.format(partition))
|
self.logger.debug('flashing {}'.format(partition))
|
||||||
self._flash_image(self.target, partition, expand_path(image_path))
|
self._flash_image(self.target, partition, expand_path(image_path))
|
||||||
fastboot_command('reboot')
|
fastboot_command('reboot')
|
||||||
self.target.connect(timeout=180)
|
if connect:
|
||||||
|
self.target.connect(timeout=180)
|
||||||
|
|
||||||
def _validate_image_bundle(self, image_bundle):
|
def _validate_image_bundle(self, image_bundle):
|
||||||
if not tarfile.is_tarfile(image_bundle):
|
if not tarfile.is_tarfile(image_bundle):
|
||||||
@ -85,7 +86,7 @@ class FastbootFlashModule(FlashModule):
|
|||||||
self._validate_image_bundle(image_bundle)
|
self._validate_image_bundle(image_bundle)
|
||||||
extract_dir = tempfile.mkdtemp()
|
extract_dir = tempfile.mkdtemp()
|
||||||
with tarfile.open(image_bundle) as tar:
|
with tarfile.open(image_bundle) as tar:
|
||||||
tar.extractall(path=extract_dir)
|
safe_extract(tar, path=extract_dir)
|
||||||
files = [tf.name for tf in tar.getmembers()]
|
files = [tf.name for tf in tar.getmembers()]
|
||||||
if self.partitions_file_name not in files:
|
if self.partitions_file_name not in files:
|
||||||
extract_dir = os.path.join(extract_dir, files[0])
|
extract_dir = os.path.join(extract_dir, files[0])
|
||||||
@ -125,4 +126,3 @@ def get_mapping(base_dir, partition_file):
|
|||||||
HostError('file {} was not found in the bundle or was misplaced'.format(pair[1]))
|
HostError('file {} was not found in the bundle or was misplaced'.format(pair[1]))
|
||||||
mapping[pair[0]] = image_path
|
mapping[pair[0]] = image_path
|
||||||
return mapping
|
return mapping
|
||||||
|
|
||||||
|
@ -60,150 +60,150 @@ class BigLittleModule(Module):
|
|||||||
|
|
||||||
def list_bigs_frequencies(self):
|
def list_bigs_frequencies(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.list_frequencies(bigs_online[0])
|
return self.target.cpufreq.list_frequencies(bigs_online[0])
|
||||||
|
|
||||||
def list_bigs_governors(self):
|
def list_bigs_governors(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.list_governors(bigs_online[0])
|
return self.target.cpufreq.list_governors(bigs_online[0])
|
||||||
|
|
||||||
def list_bigs_governor_tunables(self):
|
def list_bigs_governor_tunables(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.list_governor_tunables(bigs_online[0])
|
return self.target.cpufreq.list_governor_tunables(bigs_online[0])
|
||||||
|
|
||||||
def list_littles_frequencies(self):
|
def list_littles_frequencies(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.list_frequencies(littles_online[0])
|
return self.target.cpufreq.list_frequencies(littles_online[0])
|
||||||
|
|
||||||
def list_littles_governors(self):
|
def list_littles_governors(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.list_governors(littles_online[0])
|
return self.target.cpufreq.list_governors(littles_online[0])
|
||||||
|
|
||||||
def list_littles_governor_tunables(self):
|
def list_littles_governor_tunables(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.list_governor_tunables(littles_online[0])
|
return self.target.cpufreq.list_governor_tunables(littles_online[0])
|
||||||
|
|
||||||
def get_bigs_governor(self):
|
def get_bigs_governor(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.get_governor(bigs_online[0])
|
return self.target.cpufreq.get_governor(bigs_online[0])
|
||||||
|
|
||||||
def get_bigs_governor_tunables(self):
|
def get_bigs_governor_tunables(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.get_governor_tunables(bigs_online[0])
|
return self.target.cpufreq.get_governor_tunables(bigs_online[0])
|
||||||
|
|
||||||
def get_bigs_frequency(self):
|
def get_bigs_frequency(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.get_frequency(bigs_online[0])
|
return self.target.cpufreq.get_frequency(bigs_online[0])
|
||||||
|
|
||||||
def get_bigs_min_frequency(self):
|
def get_bigs_min_frequency(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.get_min_frequency(bigs_online[0])
|
return self.target.cpufreq.get_min_frequency(bigs_online[0])
|
||||||
|
|
||||||
def get_bigs_max_frequency(self):
|
def get_bigs_max_frequency(self):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
return self.target.cpufreq.get_max_frequency(bigs_online[0])
|
return self.target.cpufreq.get_max_frequency(bigs_online[0])
|
||||||
|
|
||||||
def get_littles_governor(self):
|
def get_littles_governor(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.get_governor(littles_online[0])
|
return self.target.cpufreq.get_governor(littles_online[0])
|
||||||
|
|
||||||
def get_littles_governor_tunables(self):
|
def get_littles_governor_tunables(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.get_governor_tunables(littles_online[0])
|
return self.target.cpufreq.get_governor_tunables(littles_online[0])
|
||||||
|
|
||||||
def get_littles_frequency(self):
|
def get_littles_frequency(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.get_frequency(littles_online[0])
|
return self.target.cpufreq.get_frequency(littles_online[0])
|
||||||
|
|
||||||
def get_littles_min_frequency(self):
|
def get_littles_min_frequency(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.get_min_frequency(littles_online[0])
|
return self.target.cpufreq.get_min_frequency(littles_online[0])
|
||||||
|
|
||||||
def get_littles_max_frequency(self):
|
def get_littles_max_frequency(self):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
return self.target.cpufreq.get_max_frequency(littles_online[0])
|
return self.target.cpufreq.get_max_frequency(littles_online[0])
|
||||||
|
|
||||||
def set_bigs_governor(self, governor, **kwargs):
|
def set_bigs_governor(self, governor, **kwargs):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
self.target.cpufreq.set_governor(bigs_online[0], governor, **kwargs)
|
self.target.cpufreq.set_governor(bigs_online[0], governor, **kwargs)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All bigs appear to be offline")
|
raise ValueError("All bigs appear to be offline")
|
||||||
|
|
||||||
def set_bigs_governor_tunables(self, governor, **kwargs):
|
def set_bigs_governor_tunables(self, governor, **kwargs):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
self.target.cpufreq.set_governor_tunables(bigs_online[0], governor, **kwargs)
|
self.target.cpufreq.set_governor_tunables(bigs_online[0], governor, **kwargs)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All bigs appear to be offline")
|
raise ValueError("All bigs appear to be offline")
|
||||||
|
|
||||||
def set_bigs_frequency(self, frequency, exact=True):
|
def set_bigs_frequency(self, frequency, exact=True):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
self.target.cpufreq.set_frequency(bigs_online[0], frequency, exact)
|
self.target.cpufreq.set_frequency(bigs_online[0], frequency, exact)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All bigs appear to be offline")
|
raise ValueError("All bigs appear to be offline")
|
||||||
|
|
||||||
def set_bigs_min_frequency(self, frequency, exact=True):
|
def set_bigs_min_frequency(self, frequency, exact=True):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
self.target.cpufreq.set_min_frequency(bigs_online[0], frequency, exact)
|
self.target.cpufreq.set_min_frequency(bigs_online[0], frequency, exact)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All bigs appear to be offline")
|
raise ValueError("All bigs appear to be offline")
|
||||||
|
|
||||||
def set_bigs_max_frequency(self, frequency, exact=True):
|
def set_bigs_max_frequency(self, frequency, exact=True):
|
||||||
bigs_online = self.bigs_online
|
bigs_online = self.bigs_online
|
||||||
if len(bigs_online) > 0:
|
if bigs_online:
|
||||||
self.target.cpufreq.set_max_frequency(bigs_online[0], frequency, exact)
|
self.target.cpufreq.set_max_frequency(bigs_online[0], frequency, exact)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All bigs appear to be offline")
|
raise ValueError("All bigs appear to be offline")
|
||||||
|
|
||||||
def set_littles_governor(self, governor, **kwargs):
|
def set_littles_governor(self, governor, **kwargs):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
self.target.cpufreq.set_governor(littles_online[0], governor, **kwargs)
|
self.target.cpufreq.set_governor(littles_online[0], governor, **kwargs)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All littles appear to be offline")
|
raise ValueError("All littles appear to be offline")
|
||||||
|
|
||||||
def set_littles_governor_tunables(self, governor, **kwargs):
|
def set_littles_governor_tunables(self, governor, **kwargs):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
self.target.cpufreq.set_governor_tunables(littles_online[0], governor, **kwargs)
|
self.target.cpufreq.set_governor_tunables(littles_online[0], governor, **kwargs)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All littles appear to be offline")
|
raise ValueError("All littles appear to be offline")
|
||||||
|
|
||||||
def set_littles_frequency(self, frequency, exact=True):
|
def set_littles_frequency(self, frequency, exact=True):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
self.target.cpufreq.set_frequency(littles_online[0], frequency, exact)
|
self.target.cpufreq.set_frequency(littles_online[0], frequency, exact)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All littles appear to be offline")
|
raise ValueError("All littles appear to be offline")
|
||||||
|
|
||||||
def set_littles_min_frequency(self, frequency, exact=True):
|
def set_littles_min_frequency(self, frequency, exact=True):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
self.target.cpufreq.set_min_frequency(littles_online[0], frequency, exact)
|
self.target.cpufreq.set_min_frequency(littles_online[0], frequency, exact)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All littles appear to be offline")
|
raise ValueError("All littles appear to be offline")
|
||||||
|
|
||||||
def set_littles_max_frequency(self, frequency, exact=True):
|
def set_littles_max_frequency(self, frequency, exact=True):
|
||||||
littles_online = self.littles_online
|
littles_online = self.littles_online
|
||||||
if len(littles_online) > 0:
|
if littles_online:
|
||||||
self.target.cpufreq.set_max_frequency(littles_online[0], frequency, exact)
|
self.target.cpufreq.set_max_frequency(littles_online[0], frequency, exact)
|
||||||
else:
|
else:
|
||||||
raise ValueError("All littles appear to be offline")
|
raise ValueError("All littles appear to be offline")
|
||||||
|
@ -16,11 +16,15 @@
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from shlex import quote
|
||||||
|
import itertools
|
||||||
|
import warnings
|
||||||
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import TargetStableError
|
||||||
from devlib.utils.misc import list_to_ranges, isiterable
|
from devlib.utils.misc import list_to_ranges, isiterable
|
||||||
from devlib.utils.types import boolean
|
from devlib.utils.types import boolean
|
||||||
|
from devlib.utils.asyn import asyncf, run
|
||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
@ -52,7 +56,8 @@ class Controller(object):
|
|||||||
self.mount_point = None
|
self.mount_point = None
|
||||||
self._cgroups = {}
|
self._cgroups = {}
|
||||||
|
|
||||||
def mount(self, target, mount_root):
|
@asyncf
|
||||||
|
async def mount(self, target, mount_root):
|
||||||
|
|
||||||
mounted = target.list_file_systems()
|
mounted = target.list_file_systems()
|
||||||
if self.mount_name in [e.device for e in mounted]:
|
if self.mount_name in [e.device for e in mounted]:
|
||||||
@ -65,16 +70,16 @@ class Controller(object):
|
|||||||
else:
|
else:
|
||||||
# Mount the controller if not already in use
|
# Mount the controller if not already in use
|
||||||
self.mount_point = target.path.join(mount_root, self.mount_name)
|
self.mount_point = target.path.join(mount_root, self.mount_name)
|
||||||
target.execute('mkdir -p {} 2>/dev/null'\
|
await target.execute.asyn('mkdir -p {} 2>/dev/null'\
|
||||||
.format(self.mount_point), as_root=True)
|
.format(self.mount_point), as_root=True)
|
||||||
target.execute('mount -t cgroup -o {} {} {}'\
|
await target.execute.asyn('mount -t cgroup -o {} {} {}'\
|
||||||
.format(','.join(self.clist),
|
.format(','.join(self.clist),
|
||||||
self.mount_name,
|
self.mount_name,
|
||||||
self.mount_point),
|
self.mount_point),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
|
|
||||||
# Check if this controller uses "noprefix" option
|
# Check if this controller uses "noprefix" option
|
||||||
output = target.execute('mount | grep "{} "'.format(self.mount_name))
|
output = await target.execute.asyn('mount | grep "{} "'.format(self.mount_name))
|
||||||
if 'noprefix' in output:
|
if 'noprefix' in output:
|
||||||
self._noprefix = True
|
self._noprefix = True
|
||||||
# self.logger.debug('Controller %s using "noprefix" option',
|
# self.logger.debug('Controller %s using "noprefix" option',
|
||||||
@ -121,18 +126,34 @@ class Controller(object):
|
|||||||
cgroups.append(cg)
|
cgroups.append(cg)
|
||||||
return cgroups
|
return cgroups
|
||||||
|
|
||||||
def move_tasks(self, source, dest, exclude=[]):
|
def move_tasks(self, source, dest, exclude=None):
|
||||||
try:
|
if isinstance(exclude, str):
|
||||||
srcg = self._cgroups[source]
|
warnings.warn("Controller.move_tasks() takes needs a _list_ of exclude patterns, not a string", DeprecationWarning)
|
||||||
dstg = self._cgroups[dest]
|
exclude = [exclude]
|
||||||
except KeyError as e:
|
|
||||||
raise ValueError('Unkown group: {}'.format(e))
|
|
||||||
output = self.target._execute_util(
|
|
||||||
'cgroups_tasks_move {} {} \'{}\''.format(
|
|
||||||
srcg.directory, dstg.directory, exclude),
|
|
||||||
as_root=True)
|
|
||||||
|
|
||||||
def move_all_tasks_to(self, dest, exclude=[]):
|
if exclude is None:
|
||||||
|
exclude = []
|
||||||
|
|
||||||
|
exclude = ' '.join(
|
||||||
|
itertools.chain.from_iterable(
|
||||||
|
('-e', quote(pattern))
|
||||||
|
for pattern in exclude
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
srcg = self.cgroup(source)
|
||||||
|
dstg = self.cgroup(dest)
|
||||||
|
|
||||||
|
self.target._execute_util( # pylint: disable=protected-access
|
||||||
|
'cgroups_tasks_move {src} {dst} {exclude}'.format(
|
||||||
|
src=quote(srcg.directory),
|
||||||
|
dst=quote(dstg.directory),
|
||||||
|
exclude=exclude,
|
||||||
|
),
|
||||||
|
as_root=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def move_all_tasks_to(self, dest, exclude=None):
|
||||||
"""
|
"""
|
||||||
Move all the tasks to the specified CGroup
|
Move all the tasks to the specified CGroup
|
||||||
|
|
||||||
@ -145,8 +166,10 @@ class Controller(object):
|
|||||||
tasks.
|
tasks.
|
||||||
|
|
||||||
:param exclude: list of commands to keep in the root CGroup
|
:param exclude: list of commands to keep in the root CGroup
|
||||||
:type exlude: list(str)
|
:type exclude: list(str)
|
||||||
"""
|
"""
|
||||||
|
if exclude is None:
|
||||||
|
exclude = []
|
||||||
|
|
||||||
if isinstance(exclude, str):
|
if isinstance(exclude, str):
|
||||||
exclude = [exclude]
|
exclude = [exclude]
|
||||||
@ -154,21 +177,16 @@ class Controller(object):
|
|||||||
raise ValueError('wrong type for "exclude" parameter, '
|
raise ValueError('wrong type for "exclude" parameter, '
|
||||||
'it must be a str or a list')
|
'it must be a str or a list')
|
||||||
|
|
||||||
logging.debug('Moving all tasks into %s', dest)
|
self.logger.debug('Moving all tasks into %s', dest)
|
||||||
|
|
||||||
# Build list of tasks to exclude
|
# Build list of tasks to exclude
|
||||||
grep_filters = ''
|
self.logger.debug(' using grep filter: %s', exclude)
|
||||||
for comm in exclude:
|
|
||||||
grep_filters += '-e {} '.format(comm)
|
|
||||||
logging.debug(' using grep filter: %s', grep_filters)
|
|
||||||
if grep_filters != '':
|
|
||||||
logging.debug(' excluding tasks which name matches:')
|
|
||||||
logging.debug(' %s', ', '.join(exclude))
|
|
||||||
|
|
||||||
for cgroup in self._cgroups:
|
for cgroup in self.list_all():
|
||||||
if cgroup != dest:
|
if cgroup != dest:
|
||||||
self.move_tasks(cgroup, dest, grep_filters)
|
self.move_tasks(cgroup, dest, exclude)
|
||||||
|
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
def tasks(self, cgroup,
|
def tasks(self, cgroup,
|
||||||
filter_tid='',
|
filter_tid='',
|
||||||
filter_tname='',
|
filter_tname='',
|
||||||
@ -203,8 +221,8 @@ class Controller(object):
|
|||||||
try:
|
try:
|
||||||
cg = self._cgroups[cgroup]
|
cg = self._cgroups[cgroup]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
raise ValueError('Unkown group: {}'.format(e))
|
raise ValueError('Unknown group: {}'.format(e))
|
||||||
output = self.target._execute_util(
|
output = self.target._execute_util( # pylint: disable=protected-access
|
||||||
'cgroups_tasks_in {}'.format(cg.directory),
|
'cgroups_tasks_in {}'.format(cg.directory),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
entries = output.splitlines()
|
entries = output.splitlines()
|
||||||
@ -234,7 +252,7 @@ class Controller(object):
|
|||||||
try:
|
try:
|
||||||
cg = self._cgroups[cgroup]
|
cg = self._cgroups[cgroup]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
raise ValueError('Unkown group: {}'.format(e))
|
raise ValueError('Unknown group: {}'.format(e))
|
||||||
output = self.target.execute(
|
output = self.target.execute(
|
||||||
'{} wc -l {}/tasks'.format(
|
'{} wc -l {}/tasks'.format(
|
||||||
self.target.busybox, cg.directory),
|
self.target.busybox, cg.directory),
|
||||||
@ -257,8 +275,9 @@ class CGroup(object):
|
|||||||
|
|
||||||
# Control cgroup path
|
# Control cgroup path
|
||||||
self.directory = controller.mount_point
|
self.directory = controller.mount_point
|
||||||
|
|
||||||
if name != '/':
|
if name != '/':
|
||||||
self.directory = self.target.path.join(controller.mount_point, name[1:])
|
self.directory = self.target.path.join(controller.mount_point, name.strip('/'))
|
||||||
|
|
||||||
# Setup path for tasks file
|
# Setup path for tasks file
|
||||||
self.tasks_file = self.target.path.join(self.directory, 'tasks')
|
self.tasks_file = self.target.path.join(self.directory, 'tasks')
|
||||||
@ -276,17 +295,15 @@ class CGroup(object):
|
|||||||
self.target.execute('[ -d {0} ]'\
|
self.target.execute('[ -d {0} ]'\
|
||||||
.format(self.directory), as_root=True)
|
.format(self.directory), as_root=True)
|
||||||
return True
|
return True
|
||||||
except TargetError:
|
except TargetStableError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
conf = {}
|
conf = {}
|
||||||
|
|
||||||
logging.debug('Reading %s attributes from:',
|
self.logger.debug('Reading %s attributes from:', self.controller.kind)
|
||||||
self.controller.kind)
|
self.logger.debug(' %s', self.directory)
|
||||||
logging.debug(' %s',
|
output = self.target._execute_util( # pylint: disable=protected-access
|
||||||
self.directory)
|
|
||||||
output = self.target._execute_util(
|
|
||||||
'cgroups_get_attributes {} {}'.format(
|
'cgroups_get_attributes {} {}'.format(
|
||||||
self.directory, self.controller.kind),
|
self.directory, self.controller.kind),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
@ -302,7 +319,7 @@ class CGroup(object):
|
|||||||
if isiterable(attrs[idx]):
|
if isiterable(attrs[idx]):
|
||||||
attrs[idx] = list_to_ranges(attrs[idx])
|
attrs[idx] = list_to_ranges(attrs[idx])
|
||||||
# Build attribute path
|
# Build attribute path
|
||||||
if self.controller._noprefix:
|
if self.controller._noprefix: # pylint: disable=protected-access
|
||||||
attr_name = '{}'.format(idx)
|
attr_name = '{}'.format(idx)
|
||||||
else:
|
else:
|
||||||
attr_name = '{}.{}'.format(self.controller.kind, idx)
|
attr_name = '{}.{}'.format(self.controller.kind, idx)
|
||||||
@ -314,7 +331,7 @@ class CGroup(object):
|
|||||||
# Set the attribute value
|
# Set the attribute value
|
||||||
try:
|
try:
|
||||||
self.target.write_value(path, attrs[idx])
|
self.target.write_value(path, attrs[idx])
|
||||||
except TargetError:
|
except TargetStableError:
|
||||||
# Check if the error is due to a non-existing attribute
|
# Check if the error is due to a non-existing attribute
|
||||||
attrs = self.get()
|
attrs = self.get()
|
||||||
if idx not in attrs:
|
if idx not in attrs:
|
||||||
@ -324,7 +341,7 @@ class CGroup(object):
|
|||||||
|
|
||||||
def get_tasks(self):
|
def get_tasks(self):
|
||||||
task_ids = self.target.read_value(self.tasks_file).split()
|
task_ids = self.target.read_value(self.tasks_file).split()
|
||||||
logging.debug('Tasks: %s', task_ids)
|
self.logger.debug('Tasks: %s', task_ids)
|
||||||
return list(map(int, task_ids))
|
return list(map(int, task_ids))
|
||||||
|
|
||||||
def add_task(self, tid):
|
def add_task(self, tid):
|
||||||
@ -363,7 +380,7 @@ class CgroupsModule(Module):
|
|||||||
|
|
||||||
# Get the list of the available controllers
|
# Get the list of the available controllers
|
||||||
subsys = self.list_subsystems()
|
subsys = self.list_subsystems()
|
||||||
if len(subsys) == 0:
|
if not subsys:
|
||||||
self.logger.warning('No CGroups controller available')
|
self.logger.warning('No CGroups controller available')
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -379,24 +396,33 @@ class CgroupsModule(Module):
|
|||||||
# Initialize controllers
|
# Initialize controllers
|
||||||
self.logger.info('Available controllers:')
|
self.logger.info('Available controllers:')
|
||||||
self.controllers = {}
|
self.controllers = {}
|
||||||
for ss in subsys:
|
|
||||||
|
async def register_controller(ss):
|
||||||
hid = ss.hierarchy
|
hid = ss.hierarchy
|
||||||
controller = Controller(ss.name, hid, hierarchy[hid])
|
controller = Controller(ss.name, hid, hierarchy[hid])
|
||||||
try:
|
try:
|
||||||
controller.mount(self.target, self.cgroup_root)
|
await controller.mount.asyn(self.target, self.cgroup_root)
|
||||||
except TargetError:
|
except TargetStableError:
|
||||||
message = 'Failed to mount "{}" controller'
|
message = 'Failed to mount "{}" controller'
|
||||||
raise TargetError(message.format(controller.kind))
|
raise TargetStableError(message.format(controller.kind))
|
||||||
self.logger.info(' %-12s : %s', controller.kind,
|
self.logger.info(' %-12s : %s', controller.kind,
|
||||||
controller.mount_point)
|
controller.mount_point)
|
||||||
self.controllers[ss.name] = controller
|
self.controllers[ss.name] = controller
|
||||||
|
|
||||||
|
run(
|
||||||
|
target.async_manager.map_concurrently(
|
||||||
|
register_controller,
|
||||||
|
subsys,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def list_subsystems(self):
|
def list_subsystems(self):
|
||||||
subsystems = []
|
subsystems = []
|
||||||
for line in self.target.execute('{} cat /proc/cgroups'\
|
for line in self.target.execute('{} cat /proc/cgroups'\
|
||||||
.format(self.target.busybox), as_root=self.target.is_rooted).splitlines()[1:]:
|
.format(self.target.busybox), as_root=self.target.is_rooted).splitlines()[1:]:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line or line.startswith('#'):
|
if not line or line.startswith('#') or line.endswith('0'):
|
||||||
continue
|
continue
|
||||||
name, hierarchy, num_cgroups, enabled = line.split()
|
name, hierarchy, num_cgroups, enabled = line.split()
|
||||||
subsystems.append(CgroupSubsystemEntry(name,
|
subsystems.append(CgroupSubsystemEntry(name,
|
||||||
@ -420,20 +446,27 @@ class CgroupsModule(Module):
|
|||||||
:param cgroup: Name of cgroup to run command into
|
:param cgroup: Name of cgroup to run command into
|
||||||
:returns: A command to run `cmdline` into `cgroup`
|
:returns: A command to run `cmdline` into `cgroup`
|
||||||
"""
|
"""
|
||||||
|
if not cgroup.startswith('/'):
|
||||||
|
message = 'cgroup name "{}" must start with "/"'.format(cgroup)
|
||||||
|
raise ValueError(message)
|
||||||
return 'CGMOUNT={} {} cgroups_run_into {} {}'\
|
return 'CGMOUNT={} {} cgroups_run_into {} {}'\
|
||||||
.format(self.cgroup_root, self.target.shutils,
|
.format(self.cgroup_root, self.target.shutils,
|
||||||
cgroup, cmdline)
|
cgroup, cmdline)
|
||||||
|
|
||||||
def run_into(self, cgroup, cmdline):
|
def run_into(self, cgroup, cmdline, as_root=None):
|
||||||
"""
|
"""
|
||||||
Run the specified command into the specified CGroup
|
Run the specified command into the specified CGroup
|
||||||
|
|
||||||
:param cmdline: Command to be run into cgroup
|
:param cmdline: Command to be run into cgroup
|
||||||
:param cgroup: Name of cgroup to run command into
|
:param cgroup: Name of cgroup to run command into
|
||||||
|
:param as_root: Specify whether to run the command as root, if not
|
||||||
|
specified will default to whether the target is rooted.
|
||||||
:returns: Output of command.
|
:returns: Output of command.
|
||||||
"""
|
"""
|
||||||
|
if as_root is None:
|
||||||
|
as_root = self.target.is_rooted
|
||||||
cmd = self.run_into_cmd(cgroup, cmdline)
|
cmd = self.run_into_cmd(cgroup, cmdline)
|
||||||
raw_output = self.target.execute(cmd)
|
raw_output = self.target.execute(cmd, as_root=as_root)
|
||||||
|
|
||||||
# First line of output comes from shutils; strip it out.
|
# First line of output comes from shutils; strip it out.
|
||||||
return raw_output.split('\n', 1)[1]
|
return raw_output.split('\n', 1)[1]
|
||||||
@ -444,11 +477,11 @@ class CgroupsModule(Module):
|
|||||||
A regexps of tasks names can be used to defined tasks which should not
|
A regexps of tasks names can be used to defined tasks which should not
|
||||||
be moved.
|
be moved.
|
||||||
"""
|
"""
|
||||||
return self.target._execute_util(
|
return self.target._execute_util( # pylint: disable=protected-access
|
||||||
'cgroups_tasks_move {} {} {}'.format(srcg, dstg, exclude),
|
'cgroups_tasks_move {} {} {}'.format(srcg, dstg, exclude),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
|
|
||||||
def isolate(self, cpus, exclude=[]):
|
def isolate(self, cpus, exclude=None):
|
||||||
"""
|
"""
|
||||||
Remove all userspace tasks from specified CPUs.
|
Remove all userspace tasks from specified CPUs.
|
||||||
|
|
||||||
@ -465,6 +498,8 @@ class CgroupsModule(Module):
|
|||||||
sandbox is the CGroup of sandboxed CPUs
|
sandbox is the CGroup of sandboxed CPUs
|
||||||
isolated is the CGroup of isolated CPUs
|
isolated is the CGroup of isolated CPUs
|
||||||
"""
|
"""
|
||||||
|
if exclude is None:
|
||||||
|
exclude = []
|
||||||
all_cpus = set(range(self.target.number_of_cpus))
|
all_cpus = set(range(self.target.number_of_cpus))
|
||||||
sbox_cpus = list(all_cpus - set(cpus))
|
sbox_cpus = list(all_cpus - set(cpus))
|
||||||
isol_cpus = list(all_cpus - set(sbox_cpus))
|
isol_cpus = list(all_cpus - set(sbox_cpus))
|
||||||
@ -483,7 +518,7 @@ class CgroupsModule(Module):
|
|||||||
|
|
||||||
return sbox_cg, isol_cg
|
return sbox_cg, isol_cg
|
||||||
|
|
||||||
def freeze(self, exclude=[], thaw=False):
|
def freeze(self, exclude=None, thaw=False):
|
||||||
"""
|
"""
|
||||||
Freeze all user-space tasks but the specified ones
|
Freeze all user-space tasks but the specified ones
|
||||||
|
|
||||||
@ -501,6 +536,9 @@ class CgroupsModule(Module):
|
|||||||
:type thaw: bool
|
:type thaw: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if exclude is None:
|
||||||
|
exclude = []
|
||||||
|
|
||||||
# Create Freezer CGroup
|
# Create Freezer CGroup
|
||||||
freezer = self.controller('freezer')
|
freezer = self.controller('freezer')
|
||||||
if freezer is None:
|
if freezer is None:
|
||||||
@ -509,7 +547,8 @@ class CgroupsModule(Module):
|
|||||||
cmd = 'cgroups_freezer_set_state {{}} {}'.format(freezer_cg.directory)
|
cmd = 'cgroups_freezer_set_state {{}} {}'.format(freezer_cg.directory)
|
||||||
|
|
||||||
if thaw:
|
if thaw:
|
||||||
# Restart froozen tasks
|
# Restart frozen tasks
|
||||||
|
# pylint: disable=protected-access
|
||||||
freezer.target._execute_util(cmd.format('THAWED'), as_root=True)
|
freezer.target._execute_util(cmd.format('THAWED'), as_root=True)
|
||||||
# Remove all tasks from freezer
|
# Remove all tasks from freezer
|
||||||
freezer.move_all_tasks_to('/')
|
freezer.move_all_tasks_to('/')
|
||||||
@ -522,7 +561,7 @@ class CgroupsModule(Module):
|
|||||||
tasks = freezer.tasks('/')
|
tasks = freezer.tasks('/')
|
||||||
|
|
||||||
# Freeze all tasks
|
# Freeze all tasks
|
||||||
|
# pylint: disable=protected-access
|
||||||
freezer.target._execute_util(cmd.format('FROZEN'), as_root=True)
|
freezer.target._execute_util(cmd.format('FROZEN'), as_root=True)
|
||||||
|
|
||||||
return tasks
|
return tasks
|
||||||
|
|
||||||
|
1976
devlib/module/cgroups2.py
Normal file
1976
devlib/module/cgroups2.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -37,12 +37,14 @@ class MbedFanActiveCoolingModule(Module):
|
|||||||
with open_serial_connection(timeout=self.timeout,
|
with open_serial_connection(timeout=self.timeout,
|
||||||
port=self.port,
|
port=self.port,
|
||||||
baudrate=self.baud) as target:
|
baudrate=self.baud) as target:
|
||||||
|
# pylint: disable=no-member
|
||||||
target.sendline('motor_{}_1'.format(self.fan_pin))
|
target.sendline('motor_{}_1'.format(self.fan_pin))
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
with open_serial_connection(timeout=self.timeout,
|
with open_serial_connection(timeout=self.timeout,
|
||||||
port=self.port,
|
port=self.port,
|
||||||
baudrate=self.baud) as target:
|
baudrate=self.baud) as target:
|
||||||
|
# pylint: disable=no-member
|
||||||
target.sendline('motor_{}_0'.format(self.fan_pin))
|
target.sendline('motor_{}_0'.format(self.fan_pin))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2018 ARM Limited
|
# Copyright 2014-2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,9 +12,11 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import TargetStableError
|
||||||
from devlib.utils.misc import memoized
|
from devlib.utils.misc import memoized
|
||||||
|
import devlib.utils.asyn as asyn
|
||||||
|
|
||||||
|
|
||||||
# a dict of governor name and a list of it tunables that can't be read
|
# a dict of governor name and a list of it tunables that can't be read
|
||||||
@ -28,44 +30,52 @@ class CpufreqModule(Module):
|
|||||||
name = 'cpufreq'
|
name = 'cpufreq'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def probe(target):
|
@asyn.asyncf
|
||||||
|
async def probe(target):
|
||||||
|
paths = [
|
||||||
|
# x86 with Intel P-State driver
|
||||||
|
(target.abi == 'x86_64', '/sys/devices/system/cpu/intel_pstate'),
|
||||||
|
# Generic CPUFreq support (single policy)
|
||||||
|
(True, '/sys/devices/system/cpu/cpufreq/policy0'),
|
||||||
|
# Generic CPUFreq support (per CPU policy)
|
||||||
|
(True, '/sys/devices/system/cpu/cpu0/cpufreq'),
|
||||||
|
]
|
||||||
|
paths = [
|
||||||
|
path[1] for path in paths
|
||||||
|
if path[0]
|
||||||
|
]
|
||||||
|
|
||||||
# x86 with Intel P-State driver
|
exists = await target.async_manager.map_concurrently(
|
||||||
if target.abi == 'x86_64':
|
target.file_exists.asyn,
|
||||||
path = '/sys/devices/system/cpu/intel_pstate'
|
paths,
|
||||||
if target.file_exists(path):
|
)
|
||||||
return True
|
|
||||||
|
|
||||||
# Generic CPUFreq support (single policy)
|
return any(exists.values())
|
||||||
path = '/sys/devices/system/cpu/cpufreq/policy0'
|
|
||||||
if target.file_exists(path):
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Generic CPUFreq support (per CPU policy)
|
|
||||||
path = '/sys/devices/system/cpu/cpu0/cpufreq'
|
|
||||||
return target.file_exists(path)
|
|
||||||
|
|
||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
super(CpufreqModule, self).__init__(target)
|
super(CpufreqModule, self).__init__(target)
|
||||||
self._governor_tunables = {}
|
self._governor_tunables = {}
|
||||||
|
|
||||||
@memoized
|
@asyn.asyncf
|
||||||
def list_governors(self, cpu):
|
@asyn.memoized_method
|
||||||
|
async def list_governors(self, cpu):
|
||||||
"""Returns a list of governors supported by the cpu."""
|
"""Returns a list of governors supported by the cpu."""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_available_governors'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_available_governors'.format(cpu)
|
||||||
output = self.target.read_value(sysfile)
|
output = await self.target.read_value.asyn(sysfile)
|
||||||
return output.strip().split()
|
return output.strip().split()
|
||||||
|
|
||||||
def get_governor(self, cpu):
|
@asyn.asyncf
|
||||||
|
async def get_governor(self, cpu):
|
||||||
"""Returns the governor currently set for the specified CPU."""
|
"""Returns the governor currently set for the specified CPU."""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_governor'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_governor'.format(cpu)
|
||||||
return self.target.read_value(sysfile)
|
return await self.target.read_value.asyn(sysfile)
|
||||||
|
|
||||||
def set_governor(self, cpu, governor, **kwargs):
|
@asyn.asyncf
|
||||||
|
async def set_governor(self, cpu, governor, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set the governor for the specified CPU.
|
Set the governor for the specified CPU.
|
||||||
See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
|
See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
|
||||||
@ -82,52 +92,165 @@ class CpufreqModule(Module):
|
|||||||
Setting the governor on any core in a cluster will also set it on all
|
Setting the governor on any core in a cluster will also set it on all
|
||||||
other cores in that cluster.
|
other cores in that cluster.
|
||||||
|
|
||||||
:raises: TargetError if governor is not supported by the CPU, or if,
|
:raises: TargetStableError if governor is not supported by the CPU, or if,
|
||||||
for some reason, the governor could not be set.
|
for some reason, the governor could not be set.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
supported = self.list_governors(cpu)
|
supported = await self.list_governors.asyn(cpu)
|
||||||
if governor not in supported:
|
if governor not in supported:
|
||||||
raise TargetError('Governor {} not supported for cpu {}'.format(governor, cpu))
|
raise TargetStableError('Governor {} not supported for cpu {}'.format(governor, cpu))
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_governor'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_governor'.format(cpu)
|
||||||
self.target.write_value(sysfile, governor)
|
await self.target.write_value.asyn(sysfile, governor)
|
||||||
self.set_governor_tunables(cpu, governor, **kwargs)
|
await self.set_governor_tunables.asyn(cpu, governor, **kwargs)
|
||||||
|
|
||||||
def list_governor_tunables(self, cpu):
|
@asyn.asynccontextmanager
|
||||||
|
async def use_governor(self, governor, cpus=None, **kwargs):
|
||||||
|
"""
|
||||||
|
Use a given governor, then restore previous governor(s)
|
||||||
|
|
||||||
|
:param governor: Governor to use on all targeted CPUs (see :meth:`set_governor`)
|
||||||
|
:type governor: str
|
||||||
|
|
||||||
|
:param cpus: CPUs affected by the governor change (all by default)
|
||||||
|
:type cpus: list
|
||||||
|
|
||||||
|
:Keyword Arguments: Governor tunables, See :meth:`set_governor_tunables`
|
||||||
|
"""
|
||||||
|
if not cpus:
|
||||||
|
cpus = await self.target.list_online_cpus.asyn()
|
||||||
|
|
||||||
|
async def get_cpu_info(cpu):
|
||||||
|
return await self.target.async_manager.concurrently((
|
||||||
|
self.get_affected_cpus.asyn(cpu),
|
||||||
|
self.get_governor.asyn(cpu),
|
||||||
|
self.get_governor_tunables.asyn(cpu),
|
||||||
|
# We won't always use the frequency, but it's much quicker to
|
||||||
|
# do concurrently anyway so do it now
|
||||||
|
self.get_frequency.asyn(cpu),
|
||||||
|
))
|
||||||
|
|
||||||
|
cpus_infos = await self.target.async_manager.map_concurrently(get_cpu_info, cpus)
|
||||||
|
|
||||||
|
# Setting a governor & tunables for a cpu will set them for all cpus in
|
||||||
|
# the same cpufreq policy, so only manipulating one cpu per domain is
|
||||||
|
# enough
|
||||||
|
domains = set(
|
||||||
|
info[0][0]
|
||||||
|
for info in cpus_infos.values()
|
||||||
|
)
|
||||||
|
|
||||||
|
await self.target.async_manager.concurrently(
|
||||||
|
self.set_governor.asyn(cpu, governor, **kwargs)
|
||||||
|
for cpu in domains
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
async def set_per_cpu_tunables(cpu):
|
||||||
|
domain, prev_gov, tunables, freq = cpus_infos[cpu]
|
||||||
|
# Per-cpu tunables are safe to set concurrently
|
||||||
|
await self.set_governor_tunables.asyn(cpu, prev_gov, per_cpu=True, **tunables)
|
||||||
|
# Special case for userspace, frequency is not seen as a tunable
|
||||||
|
if prev_gov == "userspace":
|
||||||
|
await self.set_frequency.asyn(cpu, freq)
|
||||||
|
|
||||||
|
per_cpu_tunables = self.target.async_manager.concurrently(
|
||||||
|
set_per_cpu_tunables(cpu)
|
||||||
|
for cpu in domains
|
||||||
|
)
|
||||||
|
per_cpu_tunables.__qualname__ = 'CpufreqModule.use_governor.<locals>.per_cpu_tunables'
|
||||||
|
|
||||||
|
# Non-per-cpu tunables have to be set one after the other, for each
|
||||||
|
# governor that we had to deal with.
|
||||||
|
global_tunables = {
|
||||||
|
prev_gov: (cpu, tunables)
|
||||||
|
for cpu, (domain, prev_gov, tunables, freq) in cpus_infos.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
global_tunables = self.target.async_manager.concurrently(
|
||||||
|
self.set_governor_tunables.asyn(cpu, gov, per_cpu=False, **tunables)
|
||||||
|
for gov, (cpu, tunables) in global_tunables.items()
|
||||||
|
)
|
||||||
|
global_tunables.__qualname__ = 'CpufreqModule.use_governor.<locals>.global_tunables'
|
||||||
|
|
||||||
|
# Set the governor first
|
||||||
|
await self.target.async_manager.concurrently(
|
||||||
|
self.set_governor.asyn(cpu, cpus_infos[cpu][1])
|
||||||
|
for cpu in domains
|
||||||
|
)
|
||||||
|
# And then set all the tunables concurrently. Each task has a
|
||||||
|
# specific and non-overlapping set of file to write.
|
||||||
|
await self.target.async_manager.concurrently(
|
||||||
|
(per_cpu_tunables, global_tunables)
|
||||||
|
)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def _list_governor_tunables(self, cpu, governor=None):
|
||||||
|
if isinstance(cpu, int):
|
||||||
|
cpu = 'cpu{}'.format(cpu)
|
||||||
|
|
||||||
|
if governor is None:
|
||||||
|
governor = await self.get_governor.asyn(cpu)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self._governor_tunables[governor]
|
||||||
|
except KeyError:
|
||||||
|
for per_cpu, path in (
|
||||||
|
(True, '/sys/devices/system/cpu/{}/cpufreq/{}'.format(cpu, governor)),
|
||||||
|
# On old kernels
|
||||||
|
(False, '/sys/devices/system/cpu/cpufreq/{}'.format(governor)),
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
tunables = await self.target.list_directory.asyn(path)
|
||||||
|
except TargetStableError:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
per_cpu = False
|
||||||
|
tunables = []
|
||||||
|
|
||||||
|
data = (governor, per_cpu, tunables)
|
||||||
|
self._governor_tunables[governor] = data
|
||||||
|
return data
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def list_governor_tunables(self, cpu):
|
||||||
"""Returns a list of tunables available for the governor on the specified CPU."""
|
"""Returns a list of tunables available for the governor on the specified CPU."""
|
||||||
if isinstance(cpu, int):
|
_, _, tunables = await self._list_governor_tunables.asyn(cpu)
|
||||||
cpu = 'cpu{}'.format(cpu)
|
|
||||||
governor = self.get_governor(cpu)
|
|
||||||
if governor not in self._governor_tunables:
|
|
||||||
try:
|
|
||||||
tunables_path = '/sys/devices/system/cpu/{}/cpufreq/{}'.format(cpu, governor)
|
|
||||||
self._governor_tunables[governor] = self.target.list_directory(tunables_path)
|
|
||||||
except TargetError: # probably an older kernel
|
|
||||||
try:
|
|
||||||
tunables_path = '/sys/devices/system/cpu/cpufreq/{}'.format(governor)
|
|
||||||
self._governor_tunables[governor] = self.target.list_directory(tunables_path)
|
|
||||||
except TargetError: # governor does not support tunables
|
|
||||||
self._governor_tunables[governor] = []
|
|
||||||
return self._governor_tunables[governor]
|
|
||||||
|
|
||||||
def get_governor_tunables(self, cpu):
|
|
||||||
if isinstance(cpu, int):
|
|
||||||
cpu = 'cpu{}'.format(cpu)
|
|
||||||
governor = self.get_governor(cpu)
|
|
||||||
tunables = {}
|
|
||||||
for tunable in self.list_governor_tunables(cpu):
|
|
||||||
if tunable not in WRITE_ONLY_TUNABLES.get(governor, []):
|
|
||||||
try:
|
|
||||||
path = '/sys/devices/system/cpu/{}/cpufreq/{}/{}'.format(cpu, governor, tunable)
|
|
||||||
tunables[tunable] = self.target.read_value(path)
|
|
||||||
except TargetError: # May be an older kernel
|
|
||||||
path = '/sys/devices/system/cpu/cpufreq/{}/{}'.format(governor, tunable)
|
|
||||||
tunables[tunable] = self.target.read_value(path)
|
|
||||||
return tunables
|
return tunables
|
||||||
|
|
||||||
def set_governor_tunables(self, cpu, governor=None, **kwargs):
|
@asyn.asyncf
|
||||||
|
async def get_governor_tunables(self, cpu):
|
||||||
|
if isinstance(cpu, int):
|
||||||
|
cpu = 'cpu{}'.format(cpu)
|
||||||
|
governor, _, tunable_list = await self._list_governor_tunables.asyn(cpu)
|
||||||
|
|
||||||
|
write_only = set(WRITE_ONLY_TUNABLES.get(governor, []))
|
||||||
|
tunable_list = [
|
||||||
|
tunable
|
||||||
|
for tunable in tunable_list
|
||||||
|
if tunable not in write_only
|
||||||
|
]
|
||||||
|
|
||||||
|
tunables = {}
|
||||||
|
async def get_tunable(tunable):
|
||||||
|
try:
|
||||||
|
path = '/sys/devices/system/cpu/{}/cpufreq/{}/{}'.format(cpu, governor, tunable)
|
||||||
|
x = await self.target.read_value.asyn(path)
|
||||||
|
except TargetStableError: # May be an older kernel
|
||||||
|
path = '/sys/devices/system/cpu/cpufreq/{}/{}'.format(governor, tunable)
|
||||||
|
x = await self.target.read_value.asyn(path)
|
||||||
|
return x
|
||||||
|
|
||||||
|
tunables = await self.target.async_manager.map_concurrently(get_tunable, tunable_list)
|
||||||
|
return tunables
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def set_governor_tunables(self, cpu, governor=None, per_cpu=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set tunables for the specified governor. Tunables should be specified as
|
Set tunables for the specified governor. Tunables should be specified as
|
||||||
keyword arguments. Which tunables and values are valid depends on the
|
keyword arguments. Which tunables and values are valid depends on the
|
||||||
@ -136,62 +259,66 @@ class CpufreqModule(Module):
|
|||||||
:param cpu: The cpu for which the governor will be set. ``int`` or
|
:param cpu: The cpu for which the governor will be set. ``int`` or
|
||||||
full cpu name as it appears in sysfs, e.g. ``cpu0``.
|
full cpu name as it appears in sysfs, e.g. ``cpu0``.
|
||||||
:param governor: The name of the governor. Must be all lower case.
|
:param governor: The name of the governor. Must be all lower case.
|
||||||
|
:param per_cpu: If ``None``, both per-cpu and global governor tunables
|
||||||
|
will be set. If ``True``, only per-CPU tunables will be set and if
|
||||||
|
``False``, only global tunables will be set.
|
||||||
|
|
||||||
The rest should be keyword parameters mapping tunable name onto the value to
|
The rest should be keyword parameters mapping tunable name onto the value to
|
||||||
be set for it.
|
be set for it.
|
||||||
|
|
||||||
:raises: TargetError if governor specified is not a valid governor name, or if
|
:raises: TargetStableError if governor specified is not a valid governor name, or if
|
||||||
a tunable specified is not valid for the governor, or if could not set
|
a tunable specified is not valid for the governor, or if could not set
|
||||||
tunable.
|
tunable.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if not kwargs:
|
||||||
|
return
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
if governor is None:
|
|
||||||
governor = self.get_governor(cpu)
|
governor, gov_per_cpu, valid_tunables = await self._list_governor_tunables.asyn(cpu, governor=governor)
|
||||||
valid_tunables = self.list_governor_tunables(cpu)
|
|
||||||
for tunable, value in kwargs.items():
|
for tunable, value in kwargs.items():
|
||||||
if tunable in valid_tunables:
|
if tunable in valid_tunables:
|
||||||
path = '/sys/devices/system/cpu/{}/cpufreq/{}/{}'.format(cpu, governor, tunable)
|
if per_cpu is not None and gov_per_cpu != per_cpu:
|
||||||
try:
|
continue
|
||||||
self.target.write_value(path, value)
|
|
||||||
except TargetError:
|
if gov_per_cpu:
|
||||||
if self.target.file_exists(path):
|
path = '/sys/devices/system/cpu/{}/cpufreq/{}/{}'.format(cpu, governor, tunable)
|
||||||
# File exists but we did something wrong
|
else:
|
||||||
raise
|
|
||||||
# Expected file doesn't exist, try older sysfs layout.
|
|
||||||
path = '/sys/devices/system/cpu/cpufreq/{}/{}'.format(governor, tunable)
|
path = '/sys/devices/system/cpu/cpufreq/{}/{}'.format(governor, tunable)
|
||||||
self.target.write_value(path, value)
|
|
||||||
|
await self.target.write_value.asyn(path, value)
|
||||||
else:
|
else:
|
||||||
message = 'Unexpected tunable {} for governor {} on {}.\n'.format(tunable, governor, cpu)
|
message = 'Unexpected tunable {} for governor {} on {}.\n'.format(tunable, governor, cpu)
|
||||||
message += 'Available tunables are: {}'.format(valid_tunables)
|
message += 'Available tunables are: {}'.format(valid_tunables)
|
||||||
raise TargetError(message)
|
raise TargetStableError(message)
|
||||||
|
|
||||||
@memoized
|
@asyn.asyncf
|
||||||
def list_frequencies(self, cpu):
|
@asyn.memoized_method
|
||||||
"""Returns a list of frequencies supported by the cpu or an empty list
|
async def list_frequencies(self, cpu):
|
||||||
|
"""Returns a sorted list of frequencies supported by the cpu or an empty list
|
||||||
if not could be found."""
|
if not could be found."""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
try:
|
try:
|
||||||
cmd = 'cat /sys/devices/system/cpu/{}/cpufreq/scaling_available_frequencies'.format(cpu)
|
cmd = 'cat /sys/devices/system/cpu/{}/cpufreq/scaling_available_frequencies'.format(cpu)
|
||||||
output = self.target.execute(cmd)
|
output = await self.target.execute.asyn(cmd)
|
||||||
available_frequencies = list(map(int, output.strip().split())) # pylint: disable=E1103
|
available_frequencies = list(map(int, output.strip().split())) # pylint: disable=E1103
|
||||||
except TargetError:
|
except TargetStableError:
|
||||||
# On some devices scaling_frequencies is not generated.
|
# On some devices scaling_frequencies is not generated.
|
||||||
# http://adrynalyne-teachtofish.blogspot.co.uk/2011/11/how-to-enable-scalingavailablefrequenci.html
|
# http://adrynalyne-teachtofish.blogspot.co.uk/2011/11/how-to-enable-scalingavailablefrequenci.html
|
||||||
# Fall back to parsing stats/time_in_state
|
# Fall back to parsing stats/time_in_state
|
||||||
path = '/sys/devices/system/cpu/{}/cpufreq/stats/time_in_state'.format(cpu)
|
path = '/sys/devices/system/cpu/{}/cpufreq/stats/time_in_state'.format(cpu)
|
||||||
try:
|
try:
|
||||||
out_iter = iter(self.target.read_value(path).split())
|
out_iter = (await self.target.read_value.asyn(path)).split()
|
||||||
except TargetError:
|
except TargetStableError:
|
||||||
if not self.target.file_exists(path):
|
if not self.target.file_exists(path):
|
||||||
# Probably intel_pstate. Can't get available freqs.
|
# Probably intel_pstate. Can't get available freqs.
|
||||||
return []
|
return []
|
||||||
raise
|
raise
|
||||||
|
|
||||||
available_frequencies = list(map(int, reversed([f for f, _ in zip(out_iter, out_iter)])))
|
available_frequencies = list(map(int, reversed([f for f, _ in zip(out_iter, out_iter)])))
|
||||||
return available_frequencies
|
return sorted(available_frequencies)
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
def get_max_available_frequency(self, cpu):
|
def get_max_available_frequency(self, cpu):
|
||||||
@ -200,7 +327,7 @@ class CpufreqModule(Module):
|
|||||||
could not be found.
|
could not be found.
|
||||||
"""
|
"""
|
||||||
freqs = self.list_frequencies(cpu)
|
freqs = self.list_frequencies(cpu)
|
||||||
return freqs and max(freqs) or None
|
return max(freqs) if freqs else None
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
def get_min_available_frequency(self, cpu):
|
def get_min_available_frequency(self, cpu):
|
||||||
@ -209,9 +336,10 @@ class CpufreqModule(Module):
|
|||||||
could not be found.
|
could not be found.
|
||||||
"""
|
"""
|
||||||
freqs = self.list_frequencies(cpu)
|
freqs = self.list_frequencies(cpu)
|
||||||
return freqs and min(freqs) or None
|
return min(freqs) if freqs else None
|
||||||
|
|
||||||
def get_min_frequency(self, cpu):
|
@asyn.asyncf
|
||||||
|
async def get_min_frequency(self, cpu):
|
||||||
"""
|
"""
|
||||||
Returns the min frequency currently set for the specified CPU.
|
Returns the min frequency currently set for the specified CPU.
|
||||||
|
|
||||||
@ -219,15 +347,16 @@ class CpufreqModule(Module):
|
|||||||
try to read the minimum frequency and the following exception will be
|
try to read the minimum frequency and the following exception will be
|
||||||
raised ::
|
raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_min_freq'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_min_freq'.format(cpu)
|
||||||
return self.target.read_int(sysfile)
|
return await self.target.read_int.asyn(sysfile)
|
||||||
|
|
||||||
def set_min_frequency(self, cpu, frequency, exact=True):
|
@asyn.asyncf
|
||||||
|
async def set_min_frequency(self, cpu, frequency, exact=True):
|
||||||
"""
|
"""
|
||||||
Set's the minimum value for CPU frequency. Actual frequency will
|
Set's the minimum value for CPU frequency. Actual frequency will
|
||||||
depend on the Governor used and may vary during execution. The value should be
|
depend on the Governor used and may vary during execution. The value should be
|
||||||
@ -239,26 +368,27 @@ class CpufreqModule(Module):
|
|||||||
|
|
||||||
on the device.
|
on the device.
|
||||||
|
|
||||||
:raises: TargetError if the frequency is not supported by the CPU, or if, for
|
:raises: TargetStableError if the frequency is not supported by the CPU, or if, for
|
||||||
some reason, frequency could not be set.
|
some reason, frequency could not be set.
|
||||||
:raises: ValueError if ``frequency`` is not an integer.
|
:raises: ValueError if ``frequency`` is not an integer.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
available_frequencies = self.list_frequencies(cpu)
|
available_frequencies = await self.list_frequencies.asyn(cpu)
|
||||||
try:
|
try:
|
||||||
value = int(frequency)
|
value = int(frequency)
|
||||||
if exact and available_frequencies and value not in available_frequencies:
|
if exact and available_frequencies and value not in available_frequencies:
|
||||||
raise TargetError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
|
raise TargetStableError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
|
||||||
value,
|
value,
|
||||||
available_frequencies))
|
available_frequencies))
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_min_freq'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_min_freq'.format(cpu)
|
||||||
self.target.write_value(sysfile, value)
|
await self.target.write_value.asyn(sysfile, value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
||||||
|
|
||||||
def get_frequency(self, cpu):
|
@asyn.asyncf
|
||||||
|
async def get_frequency(self, cpu, cpuinfo=False):
|
||||||
"""
|
"""
|
||||||
Returns the current frequency currently set for the specified CPU.
|
Returns the current frequency currently set for the specified CPU.
|
||||||
|
|
||||||
@ -266,15 +396,22 @@ class CpufreqModule(Module):
|
|||||||
try to read the current frequency and the following exception will be
|
try to read the current frequency and the following exception will be
|
||||||
raised ::
|
raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:param cpuinfo: Read the value in the cpuinfo interface that reflects
|
||||||
|
the actual running frequency.
|
||||||
|
|
||||||
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_cur_freq'.format(cpu)
|
|
||||||
return self.target.read_int(sysfile)
|
|
||||||
|
|
||||||
def set_frequency(self, cpu, frequency, exact=True):
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/{}'.format(
|
||||||
|
cpu,
|
||||||
|
'cpuinfo_cur_freq' if cpuinfo else 'scaling_cur_freq')
|
||||||
|
return await self.target.read_int.asyn(sysfile)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def set_frequency(self, cpu, frequency, exact=True):
|
||||||
"""
|
"""
|
||||||
Set's the minimum value for CPU frequency. Actual frequency will
|
Set's the minimum value for CPU frequency. Actual frequency will
|
||||||
depend on the Governor used and may vary during execution. The value should be
|
depend on the Governor used and may vary during execution. The value should be
|
||||||
@ -288,7 +425,7 @@ class CpufreqModule(Module):
|
|||||||
|
|
||||||
on the device (if it exists).
|
on the device (if it exists).
|
||||||
|
|
||||||
:raises: TargetError if the frequency is not supported by the CPU, or if, for
|
:raises: TargetStableError if the frequency is not supported by the CPU, or if, for
|
||||||
some reason, frequency could not be set.
|
some reason, frequency could not be set.
|
||||||
:raises: ValueError if ``frequency`` is not an integer.
|
:raises: ValueError if ``frequency`` is not an integer.
|
||||||
|
|
||||||
@ -298,19 +435,24 @@ class CpufreqModule(Module):
|
|||||||
try:
|
try:
|
||||||
value = int(frequency)
|
value = int(frequency)
|
||||||
if exact:
|
if exact:
|
||||||
available_frequencies = self.list_frequencies(cpu)
|
available_frequencies = await self.list_frequencies.asyn(cpu)
|
||||||
if available_frequencies and value not in available_frequencies:
|
if available_frequencies and value not in available_frequencies:
|
||||||
raise TargetError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
|
raise TargetStableError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
|
||||||
value,
|
value,
|
||||||
available_frequencies))
|
available_frequencies))
|
||||||
if self.get_governor(cpu) != 'userspace':
|
if await self.get_governor.asyn(cpu) != 'userspace':
|
||||||
raise TargetError('Can\'t set {} frequency; governor must be "userspace"'.format(cpu))
|
raise TargetStableError('Can\'t set {} frequency; governor must be "userspace"'.format(cpu))
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_setspeed'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_setspeed'.format(cpu)
|
||||||
self.target.write_value(sysfile, value, verify=False)
|
await self.target.write_value.asyn(sysfile, value, verify=False)
|
||||||
|
cpuinfo = await self.get_frequency.asyn(cpu, cpuinfo=True)
|
||||||
|
if cpuinfo != value:
|
||||||
|
self.logger.warning(
|
||||||
|
'The cpufreq value has not been applied properly cpuinfo={} request={}'.format(cpuinfo, value))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
||||||
|
|
||||||
def get_max_frequency(self, cpu):
|
@asyn.asyncf
|
||||||
|
async def get_max_frequency(self, cpu):
|
||||||
"""
|
"""
|
||||||
Returns the max frequency currently set for the specified CPU.
|
Returns the max frequency currently set for the specified CPU.
|
||||||
|
|
||||||
@ -318,14 +460,15 @@ class CpufreqModule(Module):
|
|||||||
try to read the maximum frequency and the following exception will be
|
try to read the maximum frequency and the following exception will be
|
||||||
raised ::
|
raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
"""
|
"""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_max_freq'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_max_freq'.format(cpu)
|
||||||
return self.target.read_int(sysfile)
|
return await self.target.read_int.asyn(sysfile)
|
||||||
|
|
||||||
def set_max_frequency(self, cpu, frequency, exact=True):
|
@asyn.asyncf
|
||||||
|
async def set_max_frequency(self, cpu, frequency, exact=True):
|
||||||
"""
|
"""
|
||||||
Set's the minimum value for CPU frequency. Actual frequency will
|
Set's the minimum value for CPU frequency. Actual frequency will
|
||||||
depend on the Governor used and may vary during execution. The value should be
|
depend on the Governor used and may vary during execution. The value should be
|
||||||
@ -337,58 +480,68 @@ class CpufreqModule(Module):
|
|||||||
|
|
||||||
on the device.
|
on the device.
|
||||||
|
|
||||||
:raises: TargetError if the frequency is not supported by the CPU, or if, for
|
:raises: TargetStableError if the frequency is not supported by the CPU, or if, for
|
||||||
some reason, frequency could not be set.
|
some reason, frequency could not be set.
|
||||||
:raises: ValueError if ``frequency`` is not an integer.
|
:raises: ValueError if ``frequency`` is not an integer.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
available_frequencies = self.list_frequencies(cpu)
|
available_frequencies = await self.list_frequencies.asyn(cpu)
|
||||||
try:
|
try:
|
||||||
value = int(frequency)
|
value = int(frequency)
|
||||||
if exact and available_frequencies and value not in available_frequencies:
|
if exact and available_frequencies and value not in available_frequencies:
|
||||||
raise TargetError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
|
raise TargetStableError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
|
||||||
value,
|
value,
|
||||||
available_frequencies))
|
available_frequencies))
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_max_freq'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_max_freq'.format(cpu)
|
||||||
self.target.write_value(sysfile, value)
|
await self.target.write_value.asyn(sysfile, value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
||||||
|
|
||||||
def set_governor_for_cpus(self, cpus, governor, **kwargs):
|
@asyn.asyncf
|
||||||
|
async def set_governor_for_cpus(self, cpus, governor, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set the governor for the specified list of CPUs.
|
Set the governor for the specified list of CPUs.
|
||||||
See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
|
See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
|
||||||
|
|
||||||
:param cpus: The list of CPU for which the governor is to be set.
|
:param cpus: The list of CPU for which the governor is to be set.
|
||||||
"""
|
"""
|
||||||
for cpu in cpus:
|
await self.target.async_manager.map_concurrently(
|
||||||
self.set_governor(cpu, governor, **kwargs)
|
self.set_governor(cpu, governor, **kwargs)
|
||||||
|
for cpu in sorted(set(cpus))
|
||||||
|
)
|
||||||
|
|
||||||
def set_frequency_for_cpus(self, cpus, freq, exact=False):
|
@asyn.asyncf
|
||||||
|
async def set_frequency_for_cpus(self, cpus, freq, exact=False):
|
||||||
"""
|
"""
|
||||||
Set the frequency for the specified list of CPUs.
|
Set the frequency for the specified list of CPUs.
|
||||||
See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
|
See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
|
||||||
|
|
||||||
:param cpus: The list of CPU for which the frequency has to be set.
|
:param cpus: The list of CPU for which the frequency has to be set.
|
||||||
"""
|
"""
|
||||||
for cpu in cpus:
|
await self.target.async_manager.map_concurrently(
|
||||||
self.set_frequency(cpu, freq, exact)
|
self.set_frequency(cpu, freq, exact)
|
||||||
|
for cpu in sorted(set(cpus))
|
||||||
|
)
|
||||||
|
|
||||||
def set_all_frequencies(self, freq):
|
@asyn.asyncf
|
||||||
|
async def set_all_frequencies(self, freq):
|
||||||
"""
|
"""
|
||||||
Set the specified (minimum) frequency for all the (online) CPUs
|
Set the specified (minimum) frequency for all the (online) CPUs
|
||||||
"""
|
"""
|
||||||
return self.target._execute_util(
|
# pylint: disable=protected-access
|
||||||
|
return await self.target._execute_util.asyn(
|
||||||
'cpufreq_set_all_frequencies {}'.format(freq),
|
'cpufreq_set_all_frequencies {}'.format(freq),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
|
|
||||||
def get_all_frequencies(self):
|
@asyn.asyncf
|
||||||
|
async def get_all_frequencies(self):
|
||||||
"""
|
"""
|
||||||
Get the current frequency for all the (online) CPUs
|
Get the current frequency for all the (online) CPUs
|
||||||
"""
|
"""
|
||||||
output = self.target._execute_util(
|
# pylint: disable=protected-access
|
||||||
|
output = await self.target._execute_util.asyn(
|
||||||
'cpufreq_get_all_frequencies', as_root=True)
|
'cpufreq_get_all_frequencies', as_root=True)
|
||||||
frequencies = {}
|
frequencies = {}
|
||||||
for x in output.splitlines():
|
for x in output.splitlines():
|
||||||
@ -398,30 +551,34 @@ class CpufreqModule(Module):
|
|||||||
frequencies[kv[0]] = kv[1]
|
frequencies[kv[0]] = kv[1]
|
||||||
return frequencies
|
return frequencies
|
||||||
|
|
||||||
def set_all_governors(self, governor):
|
@asyn.asyncf
|
||||||
|
async def set_all_governors(self, governor):
|
||||||
"""
|
"""
|
||||||
Set the specified governor for all the (online) CPUs
|
Set the specified governor for all the (online) CPUs
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self.target._execute_util(
|
# pylint: disable=protected-access
|
||||||
|
return await self.target._execute_util.asyn(
|
||||||
'cpufreq_set_all_governors {}'.format(governor),
|
'cpufreq_set_all_governors {}'.format(governor),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
except TargetError as e:
|
except TargetStableError as e:
|
||||||
if ("echo: I/O error" in str(e) or
|
if ("echo: I/O error" in str(e) or
|
||||||
"write error: Invalid argument" in str(e)):
|
"write error: Invalid argument" in str(e)):
|
||||||
|
|
||||||
cpus_unsupported = [c for c in self.target.list_online_cpus()
|
cpus_unsupported = [c for c in await self.target.list_online_cpus.asyn()
|
||||||
if governor not in self.list_governors(c)]
|
if governor not in await self.list_governors.asyn(c)]
|
||||||
raise TargetError("Governor {} unsupported for CPUs {}".format(
|
raise TargetStableError("Governor {} unsupported for CPUs {}".format(
|
||||||
governor, cpus_unsupported))
|
governor, cpus_unsupported))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def get_all_governors(self):
|
@asyn.asyncf
|
||||||
|
async def get_all_governors(self):
|
||||||
"""
|
"""
|
||||||
Get the current governor for all the (online) CPUs
|
Get the current governor for all the (online) CPUs
|
||||||
"""
|
"""
|
||||||
output = self.target._execute_util(
|
# pylint: disable=protected-access
|
||||||
|
output = await self.target._execute_util.asyn(
|
||||||
'cpufreq_get_all_governors', as_root=True)
|
'cpufreq_get_all_governors', as_root=True)
|
||||||
governors = {}
|
governors = {}
|
||||||
for x in output.splitlines():
|
for x in output.splitlines():
|
||||||
@ -431,13 +588,16 @@ class CpufreqModule(Module):
|
|||||||
governors[kv[0]] = kv[1]
|
governors[kv[0]] = kv[1]
|
||||||
return governors
|
return governors
|
||||||
|
|
||||||
def trace_frequencies(self):
|
@asyn.asyncf
|
||||||
|
async def trace_frequencies(self):
|
||||||
"""
|
"""
|
||||||
Report current frequencies on trace file
|
Report current frequencies on trace file
|
||||||
"""
|
"""
|
||||||
return self.target._execute_util('cpufreq_trace_all_frequencies', as_root=True)
|
# pylint: disable=protected-access
|
||||||
|
return await self.target._execute_util.asyn('cpufreq_trace_all_frequencies', as_root=True)
|
||||||
|
|
||||||
def get_affected_cpus(self, cpu):
|
@asyn.asyncf
|
||||||
|
async def get_affected_cpus(self, cpu):
|
||||||
"""
|
"""
|
||||||
Get the online CPUs that share a frequency domain with the given CPU
|
Get the online CPUs that share a frequency domain with the given CPU
|
||||||
"""
|
"""
|
||||||
@ -446,10 +606,12 @@ class CpufreqModule(Module):
|
|||||||
|
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/affected_cpus'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/affected_cpus'.format(cpu)
|
||||||
|
|
||||||
return [int(c) for c in self.target.read_value(sysfile).split()]
|
content = await self.target.read_value.asyn(sysfile)
|
||||||
|
return [int(c) for c in content.split()]
|
||||||
|
|
||||||
@memoized
|
@asyn.asyncf
|
||||||
def get_related_cpus(self, cpu):
|
@asyn.memoized_method
|
||||||
|
async def get_related_cpus(self, cpu):
|
||||||
"""
|
"""
|
||||||
Get the CPUs that share a frequency domain with the given CPU
|
Get the CPUs that share a frequency domain with the given CPU
|
||||||
"""
|
"""
|
||||||
@ -458,10 +620,11 @@ class CpufreqModule(Module):
|
|||||||
|
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/related_cpus'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/related_cpus'.format(cpu)
|
||||||
|
|
||||||
return [int(c) for c in self.target.read_value(sysfile).split()]
|
return [int(c) for c in (await self.target.read_value.asyn(sysfile)).split()]
|
||||||
|
|
||||||
@memoized
|
@asyn.asyncf
|
||||||
def get_driver(self, cpu):
|
@asyn.memoized_method
|
||||||
|
async def get_driver(self, cpu):
|
||||||
"""
|
"""
|
||||||
Get the name of the driver used by this cpufreq policy.
|
Get the name of the driver used by this cpufreq policy.
|
||||||
"""
|
"""
|
||||||
@ -470,15 +633,16 @@ class CpufreqModule(Module):
|
|||||||
|
|
||||||
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_driver'.format(cpu)
|
sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_driver'.format(cpu)
|
||||||
|
|
||||||
return self.target.read_value(sysfile).strip()
|
return (await self.target.read_value.asyn(sysfile)).strip()
|
||||||
|
|
||||||
def iter_domains(self):
|
@asyn.asyncf
|
||||||
|
async def iter_domains(self):
|
||||||
"""
|
"""
|
||||||
Iterate over the frequency domains in the system
|
Iterate over the frequency domains in the system
|
||||||
"""
|
"""
|
||||||
cpus = set(range(self.target.number_of_cpus))
|
cpus = set(range(self.target.number_of_cpus))
|
||||||
while cpus:
|
while cpus:
|
||||||
cpu = next(iter(cpus))
|
cpu = next(iter(cpus)) # pylint: disable=stop-iteration-return
|
||||||
domain = self.target.cpufreq.get_related_cpus(cpu)
|
domain = await self.target.cpufreq.get_related_cpus.asyn(cpu)
|
||||||
yield domain
|
yield domain
|
||||||
cpus = cpus.difference(domain)
|
cpus = cpus.difference(domain)
|
||||||
|
@ -15,9 +15,14 @@
|
|||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
from past.builtins import basestring
|
from past.builtins import basestring
|
||||||
|
|
||||||
|
from operator import attrgetter
|
||||||
|
from pprint import pformat
|
||||||
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.utils.misc import memoized
|
from devlib.exception import TargetStableError
|
||||||
from devlib.utils.types import integer, boolean
|
from devlib.utils.types import integer, boolean
|
||||||
|
from devlib.utils.misc import memoized
|
||||||
|
import devlib.utils.asyn as asyn
|
||||||
|
|
||||||
|
|
||||||
class CpuidleState(object):
|
class CpuidleState(object):
|
||||||
@ -51,22 +56,27 @@ class CpuidleState(object):
|
|||||||
self.desc = desc
|
self.desc = desc
|
||||||
self.power = power
|
self.power = power
|
||||||
self.latency = latency
|
self.latency = latency
|
||||||
|
self.residency = residency
|
||||||
self.id = self.target.path.basename(self.path)
|
self.id = self.target.path.basename(self.path)
|
||||||
self.cpu = self.target.path.basename(self.target.path.dirname(path))
|
self.cpu = self.target.path.basename(self.target.path.dirname(path))
|
||||||
|
|
||||||
def enable(self):
|
@asyn.asyncf
|
||||||
self.set('disable', 0)
|
async def enable(self):
|
||||||
|
await self.set.asyn('disable', 0)
|
||||||
|
|
||||||
def disable(self):
|
@asyn.asyncf
|
||||||
self.set('disable', 1)
|
async def disable(self):
|
||||||
|
await self.set.asyn('disable', 1)
|
||||||
|
|
||||||
def get(self, prop):
|
@asyn.asyncf
|
||||||
|
async def get(self, prop):
|
||||||
property_path = self.target.path.join(self.path, prop)
|
property_path = self.target.path.join(self.path, prop)
|
||||||
return self.target.read_value(property_path)
|
return await self.target.read_value.asyn(property_path)
|
||||||
|
|
||||||
def set(self, prop, value):
|
@asyn.asyncf
|
||||||
|
async def set(self, prop, value):
|
||||||
property_path = self.target.path.join(self.path, prop)
|
property_path = self.target.path.join(self.path, prop)
|
||||||
self.target.write_value(property_path, value)
|
await self.target.write_value.asyn(property_path, value)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, CpuidleState):
|
if isinstance(other, CpuidleState):
|
||||||
@ -91,45 +101,41 @@ class Cpuidle(Module):
|
|||||||
root_path = '/sys/devices/system/cpu/cpuidle'
|
root_path = '/sys/devices/system/cpu/cpuidle'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def probe(target):
|
@asyn.asyncf
|
||||||
return target.file_exists(Cpuidle.root_path)
|
async def probe(target):
|
||||||
|
return await target.file_exists.asyn(Cpuidle.root_path)
|
||||||
|
|
||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
super(Cpuidle, self).__init__(target)
|
super(Cpuidle, self).__init__(target)
|
||||||
self._states = {}
|
|
||||||
|
|
||||||
basepath = '/sys/devices/system/cpu/'
|
basepath = '/sys/devices/system/cpu/'
|
||||||
values_tree = self.target.read_tree_values(basepath, depth=4, check_exit_code=False)
|
values_tree = self.target.read_tree_values(basepath, depth=4, check_exit_code=False)
|
||||||
i = 0
|
|
||||||
cpu_id = 'cpu{}'.format(i)
|
|
||||||
while cpu_id in values_tree:
|
|
||||||
cpu_node = values_tree[cpu_id]
|
|
||||||
|
|
||||||
if 'cpuidle' in cpu_node:
|
self._states = {
|
||||||
idle_node = cpu_node['cpuidle']
|
cpu_name: sorted(
|
||||||
self._states[cpu_id] = []
|
(
|
||||||
j = 0
|
CpuidleState(
|
||||||
state_id = 'state{}'.format(j)
|
|
||||||
while state_id in idle_node:
|
|
||||||
state_node = idle_node[state_id]
|
|
||||||
state = CpuidleState(
|
|
||||||
self.target,
|
self.target,
|
||||||
index=j,
|
# state_name is formatted as "state42"
|
||||||
path=self.target.path.join(basepath, cpu_id, 'cpuidle', state_id),
|
index=int(state_name[len('state'):]),
|
||||||
|
path=self.target.path.join(basepath, cpu_name, 'cpuidle', state_name),
|
||||||
name=state_node['name'],
|
name=state_node['name'],
|
||||||
desc=state_node['desc'],
|
desc=state_node['desc'],
|
||||||
power=int(state_node['power']),
|
power=int(state_node['power']),
|
||||||
latency=int(state_node['latency']),
|
latency=int(state_node['latency']),
|
||||||
residency=int(state_node['residency']) if 'residency' in state_node else None,
|
residency=int(state_node['residency']) if 'residency' in state_node else None,
|
||||||
)
|
)
|
||||||
msg = 'Adding {} state {}: {} {}'
|
for state_name, state_node in cpu_node['cpuidle'].items()
|
||||||
self.logger.debug(msg.format(cpu_id, j, state.name, state.desc))
|
if state_name.startswith('state')
|
||||||
self._states[cpu_id].append(state)
|
),
|
||||||
j += 1
|
key=attrgetter('index'),
|
||||||
state_id = 'state{}'.format(j)
|
)
|
||||||
|
|
||||||
i += 1
|
for cpu_name, cpu_node in values_tree.items()
|
||||||
cpu_id = 'cpu{}'.format(i)
|
if cpu_name.startswith('cpu') and 'cpuidle' in cpu_node
|
||||||
|
}
|
||||||
|
|
||||||
|
self.logger.debug('Adding cpuidle states:\n{}'.format(pformat(self._states)))
|
||||||
|
|
||||||
def get_states(self, cpu=0):
|
def get_states(self, cpu=0):
|
||||||
if isinstance(cpu, int):
|
if isinstance(cpu, int):
|
||||||
@ -148,28 +154,67 @@ class Cpuidle(Module):
|
|||||||
return s
|
return s
|
||||||
raise ValueError('Cpuidle state {} does not exist'.format(state))
|
raise ValueError('Cpuidle state {} does not exist'.format(state))
|
||||||
|
|
||||||
def enable(self, state, cpu=0):
|
@asyn.asyncf
|
||||||
self.get_state(state, cpu).enable()
|
async def enable(self, state, cpu=0):
|
||||||
|
await self.get_state(state, cpu).enable.asyn()
|
||||||
|
|
||||||
def disable(self, state, cpu=0):
|
@asyn.asyncf
|
||||||
self.get_state(state, cpu).disable()
|
async def disable(self, state, cpu=0):
|
||||||
|
await self.get_state(state, cpu).disable.asyn()
|
||||||
|
|
||||||
def enable_all(self, cpu=0):
|
@asyn.asyncf
|
||||||
for state in self.get_states(cpu):
|
async def enable_all(self, cpu=0):
|
||||||
state.enable()
|
await self.target.async_manager.concurrently(
|
||||||
|
state.enable.asyn()
|
||||||
|
for state in self.get_states(cpu)
|
||||||
|
)
|
||||||
|
|
||||||
def disable_all(self, cpu=0):
|
@asyn.asyncf
|
||||||
for state in self.get_states(cpu):
|
async def disable_all(self, cpu=0):
|
||||||
state.disable()
|
await self.target.async_manager.concurrently(
|
||||||
|
state.disable.asyn()
|
||||||
|
for state in self.get_states(cpu)
|
||||||
|
)
|
||||||
|
|
||||||
def perturb_cpus(self):
|
@asyn.asyncf
|
||||||
|
async def perturb_cpus(self):
|
||||||
"""
|
"""
|
||||||
Momentarily wake each CPU. Ensures cpu_idle events in trace file.
|
Momentarily wake each CPU. Ensures cpu_idle events in trace file.
|
||||||
"""
|
"""
|
||||||
output = self.target._execute_util('cpuidle_wake_all_cpus')
|
# pylint: disable=protected-access
|
||||||
|
await self.target._execute_util.asyn('cpuidle_wake_all_cpus')
|
||||||
|
|
||||||
def get_driver(self):
|
@asyn.asyncf
|
||||||
return self.target.read_value(self.target.path.join(self.root_path, 'current_driver'))
|
async def get_driver(self):
|
||||||
|
return await self.target.read_value.asyn(self.target.path.join(self.root_path, 'current_driver'))
|
||||||
|
|
||||||
def get_governor(self):
|
@memoized
|
||||||
return self.target.read_value(self.target.path.join(self.root_path, 'current_governor_ro'))
|
def list_governors(self):
|
||||||
|
"""Returns a list of supported idle governors."""
|
||||||
|
sysfile = self.target.path.join(self.root_path, 'available_governors')
|
||||||
|
output = self.target.read_value(sysfile)
|
||||||
|
return output.strip().split()
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def get_governor(self):
|
||||||
|
"""Returns the currently selected idle governor."""
|
||||||
|
path = self.target.path.join(self.root_path, 'current_governor_ro')
|
||||||
|
if not await self.target.file_exists.asyn(path):
|
||||||
|
path = self.target.path.join(self.root_path, 'current_governor')
|
||||||
|
return await self.target.read_value.asyn(path)
|
||||||
|
|
||||||
|
def set_governor(self, governor):
|
||||||
|
"""
|
||||||
|
Set the idle governor for the system.
|
||||||
|
|
||||||
|
:param governor: The name of the governor to be used. This must be
|
||||||
|
supported by the specific device.
|
||||||
|
|
||||||
|
:raises TargetStableError if governor is not supported by the CPU, or
|
||||||
|
if, for some reason, the governor could not be set.
|
||||||
|
"""
|
||||||
|
supported = self.list_governors()
|
||||||
|
if governor not in supported:
|
||||||
|
raise TargetStableError('Governor {} not supported'.format(governor))
|
||||||
|
sysfile = self.target.path.join(self.root_path, 'current_governor')
|
||||||
|
self.target.write_value(sysfile, governor)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import TargetStableError
|
||||||
from devlib.utils.misc import memoized
|
from devlib.utils.misc import memoized
|
||||||
|
|
||||||
class DevfreqModule(Module):
|
class DevfreqModule(Module):
|
||||||
@ -64,13 +64,13 @@ class DevfreqModule(Module):
|
|||||||
Additional keyword arguments can be used to specify governor tunables for
|
Additional keyword arguments can be used to specify governor tunables for
|
||||||
governors that support them.
|
governors that support them.
|
||||||
|
|
||||||
:raises: TargetError if governor is not supported by the device, or if,
|
:raises: TargetStableError if governor is not supported by the device, or if,
|
||||||
for some reason, the governor could not be set.
|
for some reason, the governor could not be set.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
supported = self.list_governors(device)
|
supported = self.list_governors(device)
|
||||||
if governor not in supported:
|
if governor not in supported:
|
||||||
raise TargetError('Governor {} not supported for device {}'.format(governor, device))
|
raise TargetStableError('Governor {} not supported for device {}'.format(governor, device))
|
||||||
sysfile = '/sys/class/devfreq/{}/governor'.format(device)
|
sysfile = '/sys/class/devfreq/{}/governor'.format(device)
|
||||||
self.target.write_value(sysfile, governor)
|
self.target.write_value(sysfile, governor)
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ class DevfreqModule(Module):
|
|||||||
will try to read the minimum frequency and the following exception will
|
will try to read the minimum frequency and the following exception will
|
||||||
be raised ::
|
be raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sysfile = '/sys/class/devfreq/{}/min_freq'.format(device)
|
sysfile = '/sys/class/devfreq/{}/min_freq'.format(device)
|
||||||
@ -112,7 +112,7 @@ class DevfreqModule(Module):
|
|||||||
|
|
||||||
on the device.
|
on the device.
|
||||||
|
|
||||||
:raises: TargetError if the frequency is not supported by the device, or if, for
|
:raises: TargetStableError if the frequency is not supported by the device, or if, for
|
||||||
some reason, frequency could not be set.
|
some reason, frequency could not be set.
|
||||||
:raises: ValueError if ``frequency`` is not an integer.
|
:raises: ValueError if ``frequency`` is not an integer.
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ class DevfreqModule(Module):
|
|||||||
try:
|
try:
|
||||||
value = int(frequency)
|
value = int(frequency)
|
||||||
if exact and available_frequencies and value not in available_frequencies:
|
if exact and available_frequencies and value not in available_frequencies:
|
||||||
raise TargetError('Can\'t set {} frequency to {}\nmust be in {}'.format(device,
|
raise TargetStableError('Can\'t set {} frequency to {}\nmust be in {}'.format(device,
|
||||||
value,
|
value,
|
||||||
available_frequencies))
|
available_frequencies))
|
||||||
sysfile = '/sys/class/devfreq/{}/min_freq'.format(device)
|
sysfile = '/sys/class/devfreq/{}/min_freq'.format(device)
|
||||||
@ -137,7 +137,7 @@ class DevfreqModule(Module):
|
|||||||
will try to read the current frequency and the following exception will
|
will try to read the current frequency and the following exception will
|
||||||
be raised ::
|
be raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sysfile = '/sys/class/devfreq/{}/cur_freq'.format(device)
|
sysfile = '/sys/class/devfreq/{}/cur_freq'.format(device)
|
||||||
@ -151,7 +151,7 @@ class DevfreqModule(Module):
|
|||||||
try to read the maximum frequency and the following exception will be
|
try to read the maximum frequency and the following exception will be
|
||||||
raised ::
|
raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
"""
|
"""
|
||||||
sysfile = '/sys/class/devfreq/{}/max_freq'.format(device)
|
sysfile = '/sys/class/devfreq/{}/max_freq'.format(device)
|
||||||
return self.target.read_int(sysfile)
|
return self.target.read_int(sysfile)
|
||||||
@ -168,7 +168,7 @@ class DevfreqModule(Module):
|
|||||||
|
|
||||||
on the device.
|
on the device.
|
||||||
|
|
||||||
:raises: TargetError if the frequency is not supported by the device, or
|
:raises: TargetStableError if the frequency is not supported by the device, or
|
||||||
if, for some reason, frequency could not be set.
|
if, for some reason, frequency could not be set.
|
||||||
:raises: ValueError if ``frequency`` is not an integer.
|
:raises: ValueError if ``frequency`` is not an integer.
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ class DevfreqModule(Module):
|
|||||||
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
raise ValueError('Frequency must be an integer; got: "{}"'.format(frequency))
|
||||||
|
|
||||||
if exact and value not in available_frequencies:
|
if exact and value not in available_frequencies:
|
||||||
raise TargetError('Can\'t set {} frequency to {}\nmust be in {}'.format(device,
|
raise TargetStableError('Can\'t set {} frequency to {}\nmust be in {}'.format(device,
|
||||||
value,
|
value,
|
||||||
available_frequencies))
|
available_frequencies))
|
||||||
sysfile = '/sys/class/devfreq/{}/max_freq'.format(device)
|
sysfile = '/sys/class/devfreq/{}/max_freq'.format(device)
|
||||||
@ -200,15 +200,15 @@ class DevfreqModule(Module):
|
|||||||
Set the specified governor for all the (available) devices
|
Set the specified governor for all the (available) devices
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self.target._execute_util(
|
return self.target._execute_util( # pylint: disable=protected-access
|
||||||
'devfreq_set_all_governors {}'.format(governor), as_root=True)
|
'devfreq_set_all_governors {}'.format(governor), as_root=True)
|
||||||
except TargetError as e:
|
except TargetStableError as e:
|
||||||
if ("echo: I/O error" in str(e) or
|
if ("echo: I/O error" in str(e) or
|
||||||
"write error: Invalid argument" in str(e)):
|
"write error: Invalid argument" in str(e)):
|
||||||
|
|
||||||
devs_unsupported = [d for d in self.target.list_devices()
|
devs_unsupported = [d for d in self.target.list_devices()
|
||||||
if governor not in self.list_governors(d)]
|
if governor not in self.list_governors(d)]
|
||||||
raise TargetError("Governor {} unsupported for devices {}".format(
|
raise TargetStableError("Governor {} unsupported for devices {}".format(
|
||||||
governor, devs_unsupported))
|
governor, devs_unsupported))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
@ -217,7 +217,7 @@ class DevfreqModule(Module):
|
|||||||
"""
|
"""
|
||||||
Get the current governor for all the (online) CPUs
|
Get the current governor for all the (online) CPUs
|
||||||
"""
|
"""
|
||||||
output = self.target._execute_util(
|
output = self.target._execute_util( # pylint: disable=protected-access
|
||||||
'devfreq_get_all_governors', as_root=True)
|
'devfreq_get_all_governors', as_root=True)
|
||||||
governors = {}
|
governors = {}
|
||||||
for x in output.splitlines():
|
for x in output.splitlines():
|
||||||
@ -241,7 +241,7 @@ class DevfreqModule(Module):
|
|||||||
"""
|
"""
|
||||||
Set the specified (minimum) frequency for all the (available) devices
|
Set the specified (minimum) frequency for all the (available) devices
|
||||||
"""
|
"""
|
||||||
return self.target._execute_util(
|
return self.target._execute_util( # pylint: disable=protected-access
|
||||||
'devfreq_set_all_frequencies {}'.format(freq),
|
'devfreq_set_all_frequencies {}'.format(freq),
|
||||||
as_root=True)
|
as_root=True)
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ class DevfreqModule(Module):
|
|||||||
"""
|
"""
|
||||||
Get the current frequency for all the (available) devices
|
Get the current frequency for all the (available) devices
|
||||||
"""
|
"""
|
||||||
output = self.target._execute_util(
|
output = self.target._execute_util( # pylint: disable=protected-access
|
||||||
'devfreq_get_all_frequencies', as_root=True)
|
'devfreq_get_all_frequencies', as_root=True)
|
||||||
frequencies = {}
|
frequencies = {}
|
||||||
for x in output.splitlines():
|
for x in output.splitlines():
|
||||||
@ -258,4 +258,3 @@ class DevfreqModule(Module):
|
|||||||
break
|
break
|
||||||
frequencies[kv[0]] = kv[1]
|
frequencies[kv[0]] = kv[1]
|
||||||
return frequencies
|
return frequencies
|
||||||
|
|
||||||
|
@ -14,16 +14,13 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import logging
|
|
||||||
import os.path
|
import os.path
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
import devlib
|
from devlib.exception import TargetStableError, HostError
|
||||||
from devlib.exception import TargetError
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.platform import Platform
|
|
||||||
from devlib.platform.gem5 import Gem5SimulationPlatform
|
from devlib.platform.gem5 import Gem5SimulationPlatform
|
||||||
from devlib.utils.gem5 import iter_statistics_dump, GEM5STATS_ROI_NUMBER, GEM5STATS_DUMP_TAIL
|
from devlib.utils.gem5 import iter_statistics_dump, GEM5STATS_ROI_NUMBER
|
||||||
|
|
||||||
|
|
||||||
class Gem5ROI:
|
class Gem5ROI:
|
||||||
@ -39,7 +36,7 @@ class Gem5ROI:
|
|||||||
self.target.execute('m5 roistart {}'.format(self.number))
|
self.target.execute('m5 roistart {}'.format(self.number))
|
||||||
self.running = True
|
self.running = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if not self.running:
|
if not self.running:
|
||||||
return False
|
return False
|
||||||
@ -49,7 +46,7 @@ class Gem5ROI:
|
|||||||
|
|
||||||
class Gem5StatsModule(Module):
|
class Gem5StatsModule(Module):
|
||||||
'''
|
'''
|
||||||
Module controlling Region of Interest (ROIs) markers, satistics dump
|
Module controlling Region of Interest (ROIs) markers, satistics dump
|
||||||
frequency and parsing statistics log file when using gem5 platforms.
|
frequency and parsing statistics log file when using gem5 platforms.
|
||||||
|
|
||||||
ROIs are identified by user-defined labels and need to be booked prior to
|
ROIs are identified by user-defined labels and need to be booked prior to
|
||||||
@ -90,13 +87,13 @@ class Gem5StatsModule(Module):
|
|||||||
if label not in self.rois:
|
if label not in self.rois:
|
||||||
raise KeyError('Incorrect ROI label: {}'.format(label))
|
raise KeyError('Incorrect ROI label: {}'.format(label))
|
||||||
if not self.rois[label].start():
|
if not self.rois[label].start():
|
||||||
raise TargetError('ROI {} was already running'.format(label))
|
raise TargetStableError('ROI {} was already running'.format(label))
|
||||||
|
|
||||||
def roi_end(self, label):
|
def roi_end(self, label):
|
||||||
if label not in self.rois:
|
if label not in self.rois:
|
||||||
raise KeyError('Incorrect ROI label: {}'.format(label))
|
raise KeyError('Incorrect ROI label: {}'.format(label))
|
||||||
if not self.rois[label].stop():
|
if not self.rois[label].stop():
|
||||||
raise TargetError('ROI {} was not running'.format(label))
|
raise TargetStableError('ROI {} was not running'.format(label))
|
||||||
|
|
||||||
def start_periodic_dump(self, delay_ns=0, period_ns=10000000):
|
def start_periodic_dump(self, delay_ns=0, period_ns=10000000):
|
||||||
# Default period is 10ms because it's roughly what's needed to have
|
# Default period is 10ms because it's roughly what's needed to have
|
||||||
@ -105,7 +102,7 @@ class Gem5StatsModule(Module):
|
|||||||
msg = 'Delay ({}) and period ({}) for periodic dumps must be positive'
|
msg = 'Delay ({}) and period ({}) for periodic dumps must be positive'
|
||||||
raise ValueError(msg.format(delay_ns, period_ns))
|
raise ValueError(msg.format(delay_ns, period_ns))
|
||||||
self.target.execute('m5 dumpresetstats {} {}'.format(delay_ns, period_ns))
|
self.target.execute('m5 dumpresetstats {} {}'.format(delay_ns, period_ns))
|
||||||
|
|
||||||
def match(self, keys, rois_labels, base_dump=0):
|
def match(self, keys, rois_labels, base_dump=0):
|
||||||
'''
|
'''
|
||||||
Extract specific values from the statistics log file of gem5
|
Extract specific values from the statistics log file of gem5
|
||||||
@ -116,49 +113,49 @@ class Gem5StatsModule(Module):
|
|||||||
keys.
|
keys.
|
||||||
:type keys: list
|
:type keys: list
|
||||||
|
|
||||||
:param rois_labels: list of ROIs labels. ``match()`` returns the
|
:param rois_labels: list of ROIs labels. ``match()`` returns the
|
||||||
values of the specified fields only during dumps spanned by at
|
values of the specified fields only during dumps spanned by at
|
||||||
least one of these ROIs.
|
least one of these ROIs.
|
||||||
:type rois_label: list
|
:type rois_label: list
|
||||||
|
|
||||||
:param base_dump: dump number from which ``match()`` should operate. By
|
:param base_dump: dump number from which ``match()`` should operate. By
|
||||||
specifying a non-zero dump number, one can virtually truncate
|
specifying a non-zero dump number, one can virtually truncate
|
||||||
the head of the stats file and ignore all dumps before a specific
|
the head of the stats file and ignore all dumps before a specific
|
||||||
instant. The value of ``base_dump`` will typically (but not
|
instant. The value of ``base_dump`` will typically (but not
|
||||||
necessarily) be the result of a previous call to ``next_dump_no``.
|
necessarily) be the result of a previous call to ``next_dump_no``.
|
||||||
Default value is 0.
|
Default value is 0.
|
||||||
:type base_dump: int
|
:type base_dump: int
|
||||||
|
|
||||||
:returns: a dict indexed by key parameters containing a dict indexed by
|
:returns: a dict indexed by key parameters containing a dict indexed by
|
||||||
ROI labels containing an in-order list of records for the key under
|
ROI labels containing an in-order list of records for the key under
|
||||||
consideration during the active intervals of the ROI.
|
consideration during the active intervals of the ROI.
|
||||||
|
|
||||||
Example of return value:
|
Example of return value:
|
||||||
* Result of match(['sim_'],['roi_1']):
|
* Result of match(['sim_'],['roi_1']):
|
||||||
{
|
{
|
||||||
'sim_inst':
|
'sim_inst':
|
||||||
{
|
{
|
||||||
'roi_1': [265300176, 267975881]
|
'roi_1': [265300176, 267975881]
|
||||||
}
|
}
|
||||||
'sim_ops':
|
'sim_ops':
|
||||||
{
|
{
|
||||||
'roi_1': [324395787, 327699419]
|
'roi_1': [324395787, 327699419]
|
||||||
}
|
}
|
||||||
'sim_seconds':
|
'sim_seconds':
|
||||||
{
|
{
|
||||||
'roi_1': [0.199960, 0.199897]
|
'roi_1': [0.199960, 0.199897]
|
||||||
}
|
}
|
||||||
'sim_freq':
|
'sim_freq':
|
||||||
{
|
{
|
||||||
'roi_1': [1000000000000, 1000000000000]
|
'roi_1': [1000000000000, 1000000000000]
|
||||||
}
|
}
|
||||||
'sim_ticks':
|
'sim_ticks':
|
||||||
{
|
{
|
||||||
'roi_1': [199960234227, 199896897330]
|
'roi_1': [199960234227, 199896897330]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
records = defaultdict(lambda : defaultdict(list))
|
records = defaultdict(lambda: defaultdict(list))
|
||||||
for record, active_rois in self.match_iter(keys, rois_labels, base_dump):
|
for record, active_rois in self.match_iter(keys, rois_labels, base_dump):
|
||||||
for key in record:
|
for key in record:
|
||||||
for roi_label in active_rois:
|
for roi_label in active_rois:
|
||||||
@ -178,15 +175,15 @@ class Gem5StatsModule(Module):
|
|||||||
|
|
||||||
Example of return value:
|
Example of return value:
|
||||||
* Result of match_iter(['sim_'],['roi_1', 'roi_2']).next()
|
* Result of match_iter(['sim_'],['roi_1', 'roi_2']).next()
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
'sim_inst': 265300176,
|
'sim_inst': 265300176,
|
||||||
'sim_ops': 324395787,
|
'sim_ops': 324395787,
|
||||||
'sim_seconds': 0.199960,
|
'sim_seconds': 0.199960,
|
||||||
'sim_freq': 1000000000000,
|
'sim_freq': 1000000000000,
|
||||||
'sim_ticks': 199960234227,
|
'sim_ticks': 199960234227,
|
||||||
},
|
},
|
||||||
[ 'roi_1 ' ]
|
[ 'roi_1 ' ]
|
||||||
)
|
)
|
||||||
'''
|
'''
|
||||||
for label in rois_labels:
|
for label in rois_labels:
|
||||||
@ -195,11 +192,11 @@ class Gem5StatsModule(Module):
|
|||||||
if self.rois[label].running:
|
if self.rois[label].running:
|
||||||
self.logger.warning('Trying to match records in statistics file'
|
self.logger.warning('Trying to match records in statistics file'
|
||||||
' while ROI {} is running'.format(label))
|
' while ROI {} is running'.format(label))
|
||||||
|
|
||||||
# Construct one large regex that concatenates all keys because
|
# Construct one large regex that concatenates all keys because
|
||||||
# matching one large expression is more efficient than several smaller
|
# matching one large expression is more efficient than several smaller
|
||||||
all_keys_re = re.compile('|'.join(keys))
|
all_keys_re = re.compile('|'.join(keys))
|
||||||
|
|
||||||
def roi_active(roi_label, dump):
|
def roi_active(roi_label, dump):
|
||||||
roi = self.rois[roi_label]
|
roi = self.rois[roi_label]
|
||||||
return (roi.field in dump) and (int(dump[roi.field]) == 1)
|
return (roi.field in dump) and (int(dump[roi.field]) == 1)
|
||||||
@ -215,8 +212,8 @@ class Gem5StatsModule(Module):
|
|||||||
def next_dump_no(self):
|
def next_dump_no(self):
|
||||||
'''
|
'''
|
||||||
Returns the number of the next dump to be written to the stats file.
|
Returns the number of the next dump to be written to the stats file.
|
||||||
|
|
||||||
For example, if next_dump_no is called while there are 5 (0 to 4) full
|
For example, if next_dump_no is called while there are 5 (0 to 4) full
|
||||||
dumps in the stats file, it will return 5. This will be usefull to know
|
dumps in the stats file, it will return 5. This will be usefull to know
|
||||||
from which dump one should match() in the future to get only data from
|
from which dump one should match() in the future to get only data from
|
||||||
now on.
|
now on.
|
||||||
@ -224,7 +221,7 @@ class Gem5StatsModule(Module):
|
|||||||
with open(self._stats_file_path, 'r') as stats_file:
|
with open(self._stats_file_path, 'r') as stats_file:
|
||||||
# _goto_dump reach EOF and returns the total number of dumps + 1
|
# _goto_dump reach EOF and returns the total number of dumps + 1
|
||||||
return self._goto_dump(stats_file, sys.maxsize)
|
return self._goto_dump(stats_file, sys.maxsize)
|
||||||
|
|
||||||
def _goto_dump(self, stats_file, target_dump):
|
def _goto_dump(self, stats_file, target_dump):
|
||||||
if target_dump < 0:
|
if target_dump < 0:
|
||||||
raise HostError('Cannot go to dump {}'.format(target_dump))
|
raise HostError('Cannot go to dump {}'.format(target_dump))
|
||||||
@ -238,12 +235,12 @@ class Gem5StatsModule(Module):
|
|||||||
curr_dump = max(prev_dumps)
|
curr_dump = max(prev_dumps)
|
||||||
curr_pos = self._dump_pos_cache[curr_dump]
|
curr_pos = self._dump_pos_cache[curr_dump]
|
||||||
stats_file.seek(curr_pos)
|
stats_file.seek(curr_pos)
|
||||||
|
|
||||||
# And iterate until target_dump
|
# And iterate until target_dump
|
||||||
dump_iterator = iter_statistics_dump(stats_file)
|
dump_iterator = iter_statistics_dump(stats_file)
|
||||||
while curr_dump < target_dump:
|
while curr_dump < target_dump:
|
||||||
try:
|
try:
|
||||||
dump = next(dump_iterator)
|
next(dump_iterator)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
break
|
break
|
||||||
# End of passed dump is beginning og next one
|
# End of passed dump is beginning og next one
|
||||||
@ -251,4 +248,3 @@ class Gem5StatsModule(Module):
|
|||||||
curr_dump += 1
|
curr_dump += 1
|
||||||
self._dump_pos_cache[curr_dump] = curr_pos
|
self._dump_pos_cache[curr_dump] = curr_pos
|
||||||
return curr_dump
|
return curr_dump
|
||||||
|
|
||||||
|
@ -28,9 +28,8 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import json
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import TargetStableError
|
||||||
from devlib.utils.misc import memoized
|
from devlib.utils.misc import memoized
|
||||||
|
|
||||||
class GpufreqModule(Module):
|
class GpufreqModule(Module):
|
||||||
@ -57,7 +56,7 @@ class GpufreqModule(Module):
|
|||||||
|
|
||||||
def set_governor(self, governor):
|
def set_governor(self, governor):
|
||||||
if governor not in self.governors:
|
if governor not in self.governors:
|
||||||
raise TargetError('Governor {} not supported for gpu {}'.format(governor, cpu))
|
raise TargetStableError('Governor {} not supported for gpu'.format(governor))
|
||||||
self.target.write_value("/sys/kernel/gpu/gpu_governor", governor)
|
self.target.write_value("/sys/kernel/gpu/gpu_governor", governor)
|
||||||
|
|
||||||
def get_frequencies(self):
|
def get_frequencies(self):
|
||||||
@ -74,7 +73,7 @@ class GpufreqModule(Module):
|
|||||||
try to read the current frequency and the following exception will be
|
try to read the current frequency and the following exception will be
|
||||||
raised ::
|
raised ::
|
||||||
|
|
||||||
:raises: TargetError if for some reason the frequency could not be read.
|
:raises: TargetStableError if for some reason the frequency could not be read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return int(self.target.read_value("/sys/kernel/gpu/gpu_clock"))
|
return int(self.target.read_value("/sys/kernel/gpu/gpu_clock"))
|
||||||
@ -85,6 +84,6 @@ class GpufreqModule(Module):
|
|||||||
Returns the model name reported by the GPU.
|
Returns the model name reported by the GPU.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self.target.read_value("/sys/kernel/gpu/gpu_model")
|
return self.target.read_value("/sys/kernel/gpu/gpu_model")
|
||||||
except:
|
except: # pylint: disable=bare-except
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
|
from devlib.exception import TargetTransientError
|
||||||
|
|
||||||
|
|
||||||
class HotplugModule(Module):
|
class HotplugModule(Module):
|
||||||
@ -35,9 +36,17 @@ class HotplugModule(Module):
|
|||||||
cpu = 'cpu{}'.format(cpu)
|
cpu = 'cpu{}'.format(cpu)
|
||||||
return target.path.join(cls.base_path, cpu, 'online')
|
return target.path.join(cls.base_path, cpu, 'online')
|
||||||
|
|
||||||
def online_all(self):
|
def list_hotpluggable_cpus(self):
|
||||||
self.target._execute_util('hotplug_online_all',
|
return [cpu for cpu in range(self.target.number_of_cpus)
|
||||||
|
if self.target.file_exists(self._cpu_path(self.target, cpu))]
|
||||||
|
|
||||||
|
def online_all(self, verify=True):
|
||||||
|
self.target._execute_util('hotplug_online_all', # pylint: disable=protected-access
|
||||||
as_root=self.target.is_rooted)
|
as_root=self.target.is_rooted)
|
||||||
|
if verify:
|
||||||
|
offline = set(self.target.list_offline_cpus())
|
||||||
|
if offline:
|
||||||
|
raise TargetTransientError('The following CPUs failed to come back online: {}'.format(offline))
|
||||||
|
|
||||||
def online(self, *args):
|
def online(self, *args):
|
||||||
for cpu in args:
|
for cpu in args:
|
||||||
@ -54,3 +63,22 @@ class HotplugModule(Module):
|
|||||||
value = 1 if online else 0
|
value = 1 if online else 0
|
||||||
self.target.write_value(path, value)
|
self.target.write_value(path, value)
|
||||||
|
|
||||||
|
def _get_path(self, path):
|
||||||
|
return self.target.path.join(self.base_path,
|
||||||
|
path)
|
||||||
|
|
||||||
|
def fail(self, cpu, state):
|
||||||
|
path = self._get_path('cpu{}/hotplug/fail'.format(cpu))
|
||||||
|
return self.target.write_value(path, state)
|
||||||
|
|
||||||
|
def get_state(self, cpu):
|
||||||
|
path = self._get_path('cpu{}/hotplug/state'.format(cpu))
|
||||||
|
return self.target.read_value(path)
|
||||||
|
|
||||||
|
def get_states(self):
|
||||||
|
path = self._get_path('hotplug/states')
|
||||||
|
states_string = self.target.read_value(path)
|
||||||
|
return dict(
|
||||||
|
map(str.strip, string.split(':', 1))
|
||||||
|
for string in states_string.strip().splitlines()
|
||||||
|
)
|
||||||
|
@ -12,11 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from devlib import TargetError
|
from devlib import TargetStableError
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
from devlib.utils.types import integer
|
from devlib.utils.types import integer
|
||||||
|
|
||||||
@ -119,7 +118,7 @@ class HwmonModule(Module):
|
|||||||
def probe(target):
|
def probe(target):
|
||||||
try:
|
try:
|
||||||
target.list_directory(HWMON_ROOT, as_root=target.is_rooted)
|
target.list_directory(HWMON_ROOT, as_root=target.is_rooted)
|
||||||
except TargetError:
|
except TargetStableError:
|
||||||
# Doesn't exist or no permissions
|
# Doesn't exist or no permissions
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
@ -138,7 +137,7 @@ class HwmonModule(Module):
|
|||||||
self.scan()
|
self.scan()
|
||||||
|
|
||||||
def scan(self):
|
def scan(self):
|
||||||
values_tree = self.target.read_tree_values(self.root, depth=3)
|
values_tree = self.target.read_tree_values(self.root, depth=3, tar=True)
|
||||||
for entry_id, fields in values_tree.items():
|
for entry_id, fields in values_tree.items():
|
||||||
path = self.target.path.join(self.root, entry_id)
|
path = self.target.path.join(self.root, entry_id)
|
||||||
name = fields.pop('name', None)
|
name = fields.pop('name', None)
|
||||||
@ -147,4 +146,3 @@ class HwmonModule(Module):
|
|||||||
self.logger.debug('Adding device {}'.format(name))
|
self.logger.debug('Adding device {}'.format(name))
|
||||||
device = HwmonDevice(self.target, path, name, fields)
|
device = HwmonDevice(self.target, path, name, fields)
|
||||||
self.devices.append(device)
|
self.devices.append(device)
|
||||||
|
|
||||||
|
@ -13,28 +13,15 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Copyright 2018 Arm Limited
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from devlib.module import Module
|
|
||||||
from devlib.utils.misc import memoized
|
|
||||||
|
|
||||||
from past.builtins import basestring
|
from past.builtins import basestring
|
||||||
|
|
||||||
|
from devlib.module import Module
|
||||||
|
from devlib.utils.misc import memoized
|
||||||
|
from devlib.utils.types import boolean
|
||||||
|
from devlib.exception import TargetStableError
|
||||||
|
|
||||||
class SchedProcFSNode(object):
|
class SchedProcFSNode(object):
|
||||||
"""
|
"""
|
||||||
@ -62,7 +49,13 @@ class SchedProcFSNode(object):
|
|||||||
MC
|
MC
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_re_procfs_node = re.compile(r"(?P<name>.*)(?P<digits>\d+)$")
|
_re_procfs_node = re.compile(r"(?P<name>.*\D)(?P<digits>\d+)$")
|
||||||
|
|
||||||
|
PACKABLE_ENTRIES = [
|
||||||
|
"cpu",
|
||||||
|
"domain",
|
||||||
|
"group"
|
||||||
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _ends_with_digits(node):
|
def _ends_with_digits(node):
|
||||||
@ -83,18 +76,19 @@ class SchedProcFSNode(object):
|
|||||||
"""
|
"""
|
||||||
:returns: The name of the procfs node
|
:returns: The name of the procfs node
|
||||||
"""
|
"""
|
||||||
return re.search(SchedProcFSNode._re_procfs_node, node).group("name")
|
match = re.search(SchedProcFSNode._re_procfs_node, node)
|
||||||
|
if match:
|
||||||
|
return match.group("name")
|
||||||
|
|
||||||
@staticmethod
|
return node
|
||||||
def _packable(node, entries):
|
|
||||||
|
@classmethod
|
||||||
|
def _packable(cls, node):
|
||||||
"""
|
"""
|
||||||
:returns: Whether it makes sense to pack a node into a common entry
|
:returns: Whether it makes sense to pack a node into a common entry
|
||||||
"""
|
"""
|
||||||
return (SchedProcFSNode._ends_with_digits(node) and
|
return (SchedProcFSNode._ends_with_digits(node) and
|
||||||
any([SchedProcFSNode._ends_with_digits(x) and
|
SchedProcFSNode._node_name(node) in cls.PACKABLE_ENTRIES)
|
||||||
SchedProcFSNode._node_digits(x) != SchedProcFSNode._node_digits(node) and
|
|
||||||
SchedProcFSNode._node_name(x) == SchedProcFSNode._node_name(node)
|
|
||||||
for x in entries]))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_directory(node_name, node_data):
|
def _build_directory(node_name, node_data):
|
||||||
@ -104,7 +98,7 @@ class SchedProcFSNode(object):
|
|||||||
return SchedProcFSNode(node_data)
|
return SchedProcFSNode(node_data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_entry(node_name, node_data):
|
def _build_entry(node_data):
|
||||||
value = node_data
|
value = node_data
|
||||||
|
|
||||||
# Most nodes just contain numerical data, try to convert
|
# Most nodes just contain numerical data, try to convert
|
||||||
@ -120,7 +114,7 @@ class SchedProcFSNode(object):
|
|||||||
if isinstance(node_data, dict):
|
if isinstance(node_data, dict):
|
||||||
return SchedProcFSNode._build_directory(node_name, node_data)
|
return SchedProcFSNode._build_directory(node_name, node_data)
|
||||||
else:
|
else:
|
||||||
return SchedProcFSNode._build_entry(node_name, node_data)
|
return SchedProcFSNode._build_entry(node_data)
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return self._dyn_attrs[name]
|
return self._dyn_attrs[name]
|
||||||
@ -131,7 +125,7 @@ class SchedProcFSNode(object):
|
|||||||
# Find which entries can be packed into a common entry
|
# Find which entries can be packed into a common entry
|
||||||
packables = {
|
packables = {
|
||||||
node : SchedProcFSNode._node_name(node) + "s"
|
node : SchedProcFSNode._node_name(node) + "s"
|
||||||
for node in list(nodes.keys()) if SchedProcFSNode._packable(node, list(nodes.keys()))
|
for node in list(nodes.keys()) if SchedProcFSNode._packable(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
self._dyn_attrs = {}
|
self._dyn_attrs = {}
|
||||||
@ -152,33 +146,41 @@ class SchedProcFSNode(object):
|
|||||||
self._dyn_attrs[key] = self._build_node(key, nodes[key])
|
self._dyn_attrs[key] = self._build_node(key, nodes[key])
|
||||||
|
|
||||||
|
|
||||||
class SchedDomain(SchedProcFSNode):
|
class _SchedDomainFlag:
|
||||||
"""
|
"""
|
||||||
Represents a sched domain as seen through procfs
|
Backward-compatible emulation of the former :class:`enum.Enum` that will
|
||||||
|
work on recent kernels with dynamic sched domain flags name and no value
|
||||||
|
exposed.
|
||||||
"""
|
"""
|
||||||
# Domain flags obtained from include/linux/sched/topology.h on v4.17
|
|
||||||
# https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/+/v4.17/include/linux/sched/topology.h#20
|
|
||||||
SD_LOAD_BALANCE = 0x0001 # Do load balancing on this domain.
|
|
||||||
SD_BALANCE_NEWIDLE = 0x0002 # Balance when about to become idle
|
|
||||||
SD_BALANCE_EXEC = 0x0004 # Balance on exec
|
|
||||||
SD_BALANCE_FORK = 0x0008 # Balance on fork, clone
|
|
||||||
SD_BALANCE_WAKE = 0x0010 # Balance on wakeup
|
|
||||||
SD_WAKE_AFFINE = 0x0020 # Wake task to waking CPU
|
|
||||||
SD_ASYM_CPUCAPACITY = 0x0040 # Groups have different max cpu capacities
|
|
||||||
SD_SHARE_CPUCAPACITY = 0x0080 # Domain members share cpu capacity
|
|
||||||
SD_SHARE_POWERDOMAIN = 0x0100 # Domain members share power domain
|
|
||||||
SD_SHARE_PKG_RESOURCES = 0x0200 # Domain members share cpu pkg resources
|
|
||||||
SD_SERIALIZE = 0x0400 # Only a single load balancing instance
|
|
||||||
SD_ASYM_PACKING = 0x0800 # Place busy groups earlier in the domain
|
|
||||||
SD_PREFER_SIBLING = 0x1000 # Prefer to place tasks in a sibling domain
|
|
||||||
SD_OVERLAP = 0x2000 # sched_domains of this level overlap
|
|
||||||
SD_NUMA = 0x4000 # cross-node balancing
|
|
||||||
# Only defined in Android
|
|
||||||
# https://android.googlesource.com/kernel/common/+/android-4.14/include/linux/sched/topology.h#29
|
|
||||||
SD_SHARE_CAP_STATES = 0x8000 # Domain members share capacity state
|
|
||||||
|
|
||||||
# Checked to be valid from v4.4
|
_INSTANCES = {}
|
||||||
SD_FLAGS_REF_PARTS = (4, 4, 0)
|
"""
|
||||||
|
Dictionary storing the instances so that they can be compared with ``is``
|
||||||
|
operator.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __new__(cls, name, value, doc=None):
|
||||||
|
self = super().__new__(cls)
|
||||||
|
self.name = name
|
||||||
|
self._value = value
|
||||||
|
self.__doc__ = doc
|
||||||
|
return cls._INSTANCES.setdefault(self, self)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
# We *have to* check for "value" as well, otherwise it will be
|
||||||
|
# impossible to keep in the same set 2 instances with differing values.
|
||||||
|
return self.name == other.name and self._value == other._value
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash((self.name, self._value))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def value(self):
|
||||||
|
value = self._value
|
||||||
|
if value is None:
|
||||||
|
raise AttributeError('The kernel does not expose the sched domain flag values')
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_version(target, logger):
|
def check_version(target, logger):
|
||||||
@ -186,33 +188,162 @@ class SchedDomain(SchedProcFSNode):
|
|||||||
Check the target and see if its kernel version matches our view of the world
|
Check the target and see if its kernel version matches our view of the world
|
||||||
"""
|
"""
|
||||||
parts = target.kernel_version.parts
|
parts = target.kernel_version.parts
|
||||||
if parts < SchedDomain.SD_FLAGS_REF_PARTS:
|
# Checked to be valid from v4.4
|
||||||
|
# Not saved as a class attribute else it'll be converted to an enum
|
||||||
|
ref_parts = (4, 4, 0)
|
||||||
|
if parts < ref_parts:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"Sched domain flags are defined for kernels v{} and up, "
|
"Sched domain flags are defined for kernels v{} and up, "
|
||||||
"but target is running v{}".format(SchedDomain.SD_FLAGS_REF_PARTS, parts)
|
"but target is running v{}".format(ref_parts, parts)
|
||||||
)
|
)
|
||||||
|
|
||||||
def has_flags(self, flags):
|
def __str__(self):
|
||||||
"""
|
return self.name
|
||||||
:returns: Whether 'flags' are set on this sched domain
|
|
||||||
"""
|
|
||||||
return self.flags & flags == flags
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<SchedDomainFlag: {}>'.format(self.name)
|
||||||
|
|
||||||
|
|
||||||
|
class _SchedDomainFlagMeta(type):
|
||||||
|
"""
|
||||||
|
Metaclass of :class:`SchedDomainFlag`.
|
||||||
|
|
||||||
|
Provides some level of emulation of :class:`enum.Enum` behavior for
|
||||||
|
backward compatibility.
|
||||||
|
"""
|
||||||
|
@property
|
||||||
|
def _flags(self):
|
||||||
|
return [
|
||||||
|
attr
|
||||||
|
for name, attr in self.__dict__.items()
|
||||||
|
if name.startswith('SD_')
|
||||||
|
]
|
||||||
|
|
||||||
|
def __getitem__(self, i):
|
||||||
|
return self._flags[i]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._flags)
|
||||||
|
|
||||||
|
# These would be provided by collections.abc.Sequence, but using it on a
|
||||||
|
# metaclass seems to have issues around __init_subclass__
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._flags)
|
||||||
|
|
||||||
|
def __reversed__(self):
|
||||||
|
return reversed(self._flags)
|
||||||
|
|
||||||
|
def __contains__(self, x):
|
||||||
|
return x in self._flags
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __members__(self):
|
||||||
|
return {flag.name: flag for flag in self._flags}
|
||||||
|
|
||||||
|
|
||||||
|
class SchedDomainFlag(_SchedDomainFlag, metaclass=_SchedDomainFlagMeta):
|
||||||
|
"""
|
||||||
|
Represents a sched domain flag.
|
||||||
|
|
||||||
|
.. note:: ``SD_*`` class attributes are deprecated, new code should never
|
||||||
|
test a given flag against one of these attributes with ``is`` (.e.g ``x
|
||||||
|
is SchedDomainFlag.SD_LOAD_BALANCE``. This is because the
|
||||||
|
``SD_LOAD_BALANCE`` flag exists in two flavors that are not equal: one
|
||||||
|
with a value (the class attribute) and one without (dynamically created
|
||||||
|
when parsing flags for new kernels). Old code ran on old kernels should
|
||||||
|
work fine though.
|
||||||
|
"""
|
||||||
|
# pylint: disable=bad-whitespace
|
||||||
|
# Domain flags obtained from include/linux/sched/topology.h on v4.17
|
||||||
|
# https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/+/v4.17/include/linux/sched/topology.h#20
|
||||||
|
SD_LOAD_BALANCE = _SchedDomainFlag("SD_LOAD_BALANCE", 0x0001, "Do load balancing on this domain")
|
||||||
|
SD_BALANCE_NEWIDLE = _SchedDomainFlag("SD_BALANCE_NEWIDLE", 0x0002, "Balance when about to become idle")
|
||||||
|
SD_BALANCE_EXEC = _SchedDomainFlag("SD_BALANCE_EXEC", 0x0004, "Balance on exec")
|
||||||
|
SD_BALANCE_FORK = _SchedDomainFlag("SD_BALANCE_FORK", 0x0008, "Balance on fork, clone")
|
||||||
|
SD_BALANCE_WAKE = _SchedDomainFlag("SD_BALANCE_WAKE", 0x0010, "Balance on wakeup")
|
||||||
|
SD_WAKE_AFFINE = _SchedDomainFlag("SD_WAKE_AFFINE", 0x0020, "Wake task to waking CPU")
|
||||||
|
SD_ASYM_CPUCAPACITY = _SchedDomainFlag("SD_ASYM_CPUCAPACITY", 0x0040, "Groups have different max cpu capacities")
|
||||||
|
SD_SHARE_CPUCAPACITY = _SchedDomainFlag("SD_SHARE_CPUCAPACITY", 0x0080, "Domain members share cpu capacity")
|
||||||
|
SD_SHARE_POWERDOMAIN = _SchedDomainFlag("SD_SHARE_POWERDOMAIN", 0x0100, "Domain members share power domain")
|
||||||
|
SD_SHARE_PKG_RESOURCES = _SchedDomainFlag("SD_SHARE_PKG_RESOURCES", 0x0200, "Domain members share cpu pkg resources")
|
||||||
|
SD_SERIALIZE = _SchedDomainFlag("SD_SERIALIZE", 0x0400, "Only a single load balancing instance")
|
||||||
|
SD_ASYM_PACKING = _SchedDomainFlag("SD_ASYM_PACKING", 0x0800, "Place busy groups earlier in the domain")
|
||||||
|
SD_PREFER_SIBLING = _SchedDomainFlag("SD_PREFER_SIBLING", 0x1000, "Prefer to place tasks in a sibling domain")
|
||||||
|
SD_OVERLAP = _SchedDomainFlag("SD_OVERLAP", 0x2000, "Sched_domains of this level overlap")
|
||||||
|
SD_NUMA = _SchedDomainFlag("SD_NUMA", 0x4000, "Cross-node balancing")
|
||||||
|
# Only defined in Android
|
||||||
|
# https://android.googlesource.com/kernel/common/+/android-4.14/include/linux/sched/topology.h#29
|
||||||
|
SD_SHARE_CAP_STATES = _SchedDomainFlag("SD_SHARE_CAP_STATES", 0x8000, "(Android only) Domain members share capacity state")
|
||||||
|
|
||||||
|
|
||||||
|
class SchedDomain(SchedProcFSNode):
|
||||||
|
"""
|
||||||
|
Represents a sched domain as seen through procfs
|
||||||
|
"""
|
||||||
|
def __init__(self, nodes):
|
||||||
|
super().__init__(nodes)
|
||||||
|
|
||||||
|
flags = self.flags
|
||||||
|
# Recent kernels now have a space-separated list of flags instead of a
|
||||||
|
# packed bitfield
|
||||||
|
if isinstance(flags, str):
|
||||||
|
flags = {
|
||||||
|
_SchedDomainFlag(name=name, value=None)
|
||||||
|
for name in flags.split()
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
def has_flag(flags, flag):
|
||||||
|
return flags & flag.value == flag.value
|
||||||
|
|
||||||
|
flags = {
|
||||||
|
flag
|
||||||
|
for flag in SchedDomainFlag
|
||||||
|
if has_flag(flags, flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.flags = flags
|
||||||
|
|
||||||
|
def _select_path(target, paths, name):
|
||||||
|
for p in paths:
|
||||||
|
if target.file_exists(p):
|
||||||
|
return p
|
||||||
|
|
||||||
|
raise TargetStableError('No {} found. Tried: {}'.format(name, ', '.join(paths)))
|
||||||
|
|
||||||
class SchedProcFSData(SchedProcFSNode):
|
class SchedProcFSData(SchedProcFSNode):
|
||||||
"""
|
"""
|
||||||
Root class for creating & storing SchedProcFSNode instances
|
Root class for creating & storing SchedProcFSNode instances
|
||||||
"""
|
"""
|
||||||
_read_depth = 6
|
_read_depth = 6
|
||||||
sched_domain_root = '/proc/sys/kernel/sched_domain'
|
|
||||||
|
@classmethod
|
||||||
|
def get_data_root(cls, target):
|
||||||
|
# Location differs depending on kernel version
|
||||||
|
paths = ['/sys/kernel/debug/sched/domains/', '/proc/sys/kernel/sched_domain']
|
||||||
|
return _select_path(target, paths, "sched_domain debug directory")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def available(target):
|
def available(target):
|
||||||
return target.directory_exists(SchedProcFSData.sched_domain_root)
|
try:
|
||||||
|
path = SchedProcFSData.get_data_root(target)
|
||||||
|
except TargetStableError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
cpus = target.list_directory(path, as_root=target.is_rooted)
|
||||||
|
if not cpus:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Even if we have a CPU entry, it can be empty (e.g. hotplugged out)
|
||||||
|
# Make sure some data is there
|
||||||
|
for cpu in cpus:
|
||||||
|
if target.file_exists(target.path.join(path, cpu, "domain0", "flags")):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def __init__(self, target, path=None):
|
def __init__(self, target, path=None):
|
||||||
if not path:
|
if path is None:
|
||||||
path = self.sched_domain_root
|
path = SchedProcFSData.get_data_root(target)
|
||||||
|
|
||||||
procfs = target.read_tree_values(path, depth=self._read_depth)
|
procfs = target.read_tree_values(path, depth=self._read_depth)
|
||||||
super(SchedProcFSData, self).__init__(procfs)
|
super(SchedProcFSData, self).__init__(procfs)
|
||||||
@ -227,16 +358,142 @@ class SchedModule(Module):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def probe(target):
|
def probe(target):
|
||||||
logger = logging.getLogger(SchedModule.name)
|
logger = logging.getLogger(SchedModule.name)
|
||||||
SchedDomain.check_version(target, logger)
|
SchedDomainFlag.check_version(target, logger)
|
||||||
|
|
||||||
return SchedProcFSData.available(target)
|
# It makes sense to load this module if at least one of those
|
||||||
|
# functionalities is enabled
|
||||||
|
schedproc = SchedProcFSData.available(target)
|
||||||
|
debug = SchedModule.target_has_debug(target)
|
||||||
|
dmips = any([target.file_exists(SchedModule.cpu_dmips_capacity_path(target, cpu))
|
||||||
|
for cpu in target.list_online_cpus()])
|
||||||
|
|
||||||
|
logger.info("Scheduler sched_domain procfs entries %s",
|
||||||
|
"found" if schedproc else "not found")
|
||||||
|
logger.info("Detected kernel compiled with SCHED_DEBUG=%s",
|
||||||
|
"y" if debug else "n")
|
||||||
|
logger.info("CPU capacity sysfs entries %s",
|
||||||
|
"found" if dmips else "not found")
|
||||||
|
|
||||||
|
return schedproc or debug or dmips
|
||||||
|
|
||||||
|
def __init__(self, target):
|
||||||
|
super().__init__(target)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_sched_features_path(cls, target):
|
||||||
|
# Location differs depending on kernel version
|
||||||
|
paths = ['/sys/kernel/debug/sched/features', '/sys/kernel/debug/sched_features']
|
||||||
|
return _select_path(target, paths, "sched_features file")
|
||||||
|
|
||||||
|
def get_kernel_attributes(self, matching=None, check_exit_code=True):
|
||||||
|
"""
|
||||||
|
Get the value of scheduler attributes.
|
||||||
|
|
||||||
|
:param matching: an (optional) substring to filter the scheduler
|
||||||
|
attributes to be returned.
|
||||||
|
|
||||||
|
The scheduler exposes a list of tunable attributes under:
|
||||||
|
/proc/sys/kernel
|
||||||
|
all starting with the "sched_" prefix.
|
||||||
|
|
||||||
|
This method returns a dictionary of all the "sched_" attributes exposed
|
||||||
|
by the target kernel, within the prefix removed.
|
||||||
|
It's possible to restrict the list of attributes by specifying a
|
||||||
|
substring to be matched.
|
||||||
|
|
||||||
|
returns: a dictionary of scheduler tunables
|
||||||
|
"""
|
||||||
|
command = 'sched_get_kernel_attributes {}'.format(
|
||||||
|
matching if matching else ''
|
||||||
|
)
|
||||||
|
output = self.target._execute_util(command, as_root=self.target.is_rooted,
|
||||||
|
check_exit_code=check_exit_code)
|
||||||
|
result = {}
|
||||||
|
for entry in output.strip().split('\n'):
|
||||||
|
if ':' not in entry:
|
||||||
|
continue
|
||||||
|
path, value = entry.strip().split(':', 1)
|
||||||
|
if value in ['0', '1']:
|
||||||
|
value = bool(int(value))
|
||||||
|
elif value.isdigit():
|
||||||
|
value = int(value)
|
||||||
|
result[path] = value
|
||||||
|
return result
|
||||||
|
|
||||||
|
def set_kernel_attribute(self, attr, value, verify=True):
|
||||||
|
"""
|
||||||
|
Set the value of a scheduler attribute.
|
||||||
|
|
||||||
|
:param attr: the attribute to set, without the "sched_" prefix
|
||||||
|
:param value: the value to set
|
||||||
|
:param verify: true to check that the requested value has been set
|
||||||
|
|
||||||
|
:raise TargetError: if the attribute cannot be set
|
||||||
|
"""
|
||||||
|
if isinstance(value, bool):
|
||||||
|
value = '1' if value else '0'
|
||||||
|
elif isinstance(value, int):
|
||||||
|
value = str(value)
|
||||||
|
path = '/proc/sys/kernel/sched_' + attr
|
||||||
|
self.target.write_value(path, value, verify)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def target_has_debug(cls, target):
|
||||||
|
if target.config.get('SCHED_DEBUG') != 'y':
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
cls.get_sched_features_path(target)
|
||||||
|
return True
|
||||||
|
except TargetStableError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_features(self):
|
||||||
|
"""
|
||||||
|
Get the status of each sched feature
|
||||||
|
|
||||||
|
:returns: a dictionary of features and their "is enabled" status
|
||||||
|
"""
|
||||||
|
feats = self.target.read_value(self.get_sched_features_path(self.target))
|
||||||
|
features = {}
|
||||||
|
for feat in feats.split():
|
||||||
|
value = True
|
||||||
|
if feat.startswith('NO'):
|
||||||
|
feat = feat.replace('NO_', '', 1)
|
||||||
|
value = False
|
||||||
|
features[feat] = value
|
||||||
|
return features
|
||||||
|
|
||||||
|
def set_feature(self, feature, enable, verify=True):
|
||||||
|
"""
|
||||||
|
Set the status of a specified scheduler feature
|
||||||
|
|
||||||
|
:param feature: the feature name to set
|
||||||
|
:param enable: true to enable the feature, false otherwise
|
||||||
|
|
||||||
|
:raise ValueError: if the specified enable value is not bool
|
||||||
|
:raise RuntimeError: if the specified feature cannot be set
|
||||||
|
"""
|
||||||
|
feature = feature.upper()
|
||||||
|
feat_value = feature
|
||||||
|
if not boolean(enable):
|
||||||
|
feat_value = 'NO_' + feat_value
|
||||||
|
self.target.write_value(self.get_sched_features_path(self.target),
|
||||||
|
feat_value, verify=False)
|
||||||
|
if not verify:
|
||||||
|
return
|
||||||
|
msg = 'Failed to set {}, feature not supported?'.format(feat_value)
|
||||||
|
features = self.get_features()
|
||||||
|
feat_value = features.get(feature, not enable)
|
||||||
|
if feat_value != enable:
|
||||||
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
def get_cpu_sd_info(self, cpu):
|
def get_cpu_sd_info(self, cpu):
|
||||||
"""
|
"""
|
||||||
:returns: An object view of /proc/sys/kernel/sched_domain/cpu<cpu>/*
|
:returns: An object view of the sched_domain debug directory of 'cpu'
|
||||||
"""
|
"""
|
||||||
path = self.target.path.join(
|
path = self.target.path.join(
|
||||||
SchedProcFSData.sched_domain_root,
|
SchedProcFSData.get_data_root(self.target),
|
||||||
"cpu{}".format(cpu)
|
"cpu{}".format(cpu)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -244,7 +501,7 @@ class SchedModule(Module):
|
|||||||
|
|
||||||
def get_sd_info(self):
|
def get_sd_info(self):
|
||||||
"""
|
"""
|
||||||
:returns: An object view of /proc/sys/kernel/sched_domain/*
|
:returns: An object view of the entire sched_domain debug directory
|
||||||
"""
|
"""
|
||||||
return SchedProcFSData(self.target)
|
return SchedProcFSData(self.target)
|
||||||
|
|
||||||
@ -260,17 +517,26 @@ class SchedModule(Module):
|
|||||||
:returns: Whether energy model data is available for 'cpu'
|
:returns: Whether energy model data is available for 'cpu'
|
||||||
"""
|
"""
|
||||||
if not sd:
|
if not sd:
|
||||||
sd = SchedProcFSData(self.target, cpu)
|
sd = self.get_cpu_sd_info(cpu)
|
||||||
|
|
||||||
return sd.procfs["domain0"].get("group0", {}).get("energy", {}).get("cap_states") != None
|
return sd.procfs["domain0"].get("group0", {}).get("energy", {}).get("cap_states") != None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def cpu_dmips_capacity_path(cls, target, cpu):
|
||||||
|
"""
|
||||||
|
:returns: The target sysfs path where the dmips capacity data should be
|
||||||
|
"""
|
||||||
|
return target.path.join(
|
||||||
|
cls.cpu_sysfs_root,
|
||||||
|
'cpu{}/cpu_capacity'.format(cpu))
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
def has_dmips_capacity(self, cpu):
|
def has_dmips_capacity(self, cpu):
|
||||||
"""
|
"""
|
||||||
:returns: Whether dmips capacity data is available for 'cpu'
|
:returns: Whether dmips capacity data is available for 'cpu'
|
||||||
"""
|
"""
|
||||||
return self.target.file_exists(
|
return self.target.file_exists(
|
||||||
self.target.path.join(self.cpu_sysfs_root, 'cpu{}/cpu_capacity'.format(cpu))
|
self.cpu_dmips_capacity_path(self.target, cpu)
|
||||||
)
|
)
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
@ -279,10 +545,13 @@ class SchedModule(Module):
|
|||||||
:returns: The maximum capacity value exposed by the EAS energy model
|
:returns: The maximum capacity value exposed by the EAS energy model
|
||||||
"""
|
"""
|
||||||
if not sd:
|
if not sd:
|
||||||
sd = SchedProcFSData(self.target, cpu)
|
sd = self.get_cpu_sd_info(cpu)
|
||||||
|
|
||||||
cap_states = sd.domains[0].groups[0].energy.cap_states
|
cap_states = sd.domains[0].groups[0].energy.cap_states
|
||||||
return int(cap_states.split('\t')[-2])
|
cap_states_list = cap_states.split('\t')
|
||||||
|
num_cap_states = sd.domains[0].groups[0].energy.nr_cap_states
|
||||||
|
max_cap_index = -1 * int(len(cap_states_list) / num_cap_states)
|
||||||
|
return int(cap_states_list[max_cap_index])
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
def get_dmips_capacity(self, cpu):
|
def get_dmips_capacity(self, cpu):
|
||||||
@ -290,14 +559,9 @@ class SchedModule(Module):
|
|||||||
:returns: The capacity value generated from the capacity-dmips-mhz DT entry
|
:returns: The capacity value generated from the capacity-dmips-mhz DT entry
|
||||||
"""
|
"""
|
||||||
return self.target.read_value(
|
return self.target.read_value(
|
||||||
self.target.path.join(
|
self.cpu_dmips_capacity_path(self.target, cpu), int
|
||||||
self.cpu_sysfs_root,
|
|
||||||
'cpu{}/cpu_capacity'.format(cpu)
|
|
||||||
),
|
|
||||||
int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@memoized
|
|
||||||
def get_capacities(self, default=None):
|
def get_capacities(self, default=None):
|
||||||
"""
|
"""
|
||||||
:param default: Default capacity value to find if no data is
|
:param default: Default capacity value to find if no data is
|
||||||
@ -308,16 +572,30 @@ class SchedModule(Module):
|
|||||||
:raises RuntimeError: Raised when no capacity information is
|
:raises RuntimeError: Raised when no capacity information is
|
||||||
found and 'default' is None
|
found and 'default' is None
|
||||||
"""
|
"""
|
||||||
cpus = list(range(self.target.number_of_cpus))
|
cpus = self.target.list_online_cpus()
|
||||||
|
|
||||||
capacities = {}
|
capacities = {}
|
||||||
sd_info = self.get_sd_info()
|
|
||||||
|
|
||||||
for cpu in cpus:
|
for cpu in cpus:
|
||||||
|
if self.has_dmips_capacity(cpu):
|
||||||
|
capacities[cpu] = self.get_dmips_capacity(cpu)
|
||||||
|
|
||||||
|
missing_cpus = set(cpus).difference(capacities.keys())
|
||||||
|
if not missing_cpus:
|
||||||
|
return capacities
|
||||||
|
|
||||||
|
if not SchedProcFSData.available(self.target):
|
||||||
|
if default != None:
|
||||||
|
capacities.update({cpu : default for cpu in missing_cpus})
|
||||||
|
return capacities
|
||||||
|
else:
|
||||||
|
raise RuntimeError(
|
||||||
|
'No capacity data for cpus {}'.format(sorted(missing_cpus)))
|
||||||
|
|
||||||
|
sd_info = self.get_sd_info()
|
||||||
|
for cpu in missing_cpus:
|
||||||
if self.has_em(cpu, sd_info.cpus[cpu]):
|
if self.has_em(cpu, sd_info.cpus[cpu]):
|
||||||
capacities[cpu] = self.get_em_capacity(cpu, sd_info.cpus[cpu])
|
capacities[cpu] = self.get_em_capacity(cpu, sd_info.cpus[cpu])
|
||||||
elif self.has_dmips_capacity(cpu):
|
|
||||||
capacities[cpu] = self.get_dmips_capacity(cpu)
|
|
||||||
else:
|
else:
|
||||||
if default != None:
|
if default != None:
|
||||||
capacities[cpu] = default
|
capacities[cpu] = default
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import logging
|
||||||
|
import devlib.utils.asyn as asyn
|
||||||
|
|
||||||
from devlib.module import Module
|
from devlib.module import Module
|
||||||
|
from devlib.exception import TargetStableCalledProcessError
|
||||||
|
|
||||||
class TripPoint(object):
|
class TripPoint(object):
|
||||||
def __init__(self, zone, _id):
|
def __init__(self, zone, _id):
|
||||||
@ -27,19 +30,22 @@ class TripPoint(object):
|
|||||||
def target(self):
|
def target(self):
|
||||||
return self.zone.target
|
return self.zone.target
|
||||||
|
|
||||||
def get_temperature(self):
|
@asyn.asyncf
|
||||||
|
async def get_temperature(self):
|
||||||
"""Returns the currently configured temperature of the trip point"""
|
"""Returns the currently configured temperature of the trip point"""
|
||||||
temp_file = self.target.path.join(self.zone.path, self.temp_node)
|
temp_file = self.target.path.join(self.zone.path, self.temp_node)
|
||||||
return self.target.read_int(temp_file)
|
return await self.target.read_int.asyn(temp_file)
|
||||||
|
|
||||||
def set_temperature(self, temperature):
|
@asyn.asyncf
|
||||||
|
async def set_temperature(self, temperature):
|
||||||
temp_file = self.target.path.join(self.zone.path, self.temp_node)
|
temp_file = self.target.path.join(self.zone.path, self.temp_node)
|
||||||
self.target.write_value(temp_file, temperature)
|
await self.target.write_value.asyn(temp_file, temperature)
|
||||||
|
|
||||||
def get_type(self):
|
@asyn.asyncf
|
||||||
|
async def get_type(self):
|
||||||
"""Returns the type of trip point"""
|
"""Returns the type of trip point"""
|
||||||
type_file = self.target.path.join(self.zone.path, self.type_node)
|
type_file = self.target.path.join(self.zone.path, self.type_node)
|
||||||
return self.target.read_value(type_file)
|
return await self.target.read_value.asyn(type_file)
|
||||||
|
|
||||||
class ThermalZone(object):
|
class ThermalZone(object):
|
||||||
def __init__(self, target, root, _id):
|
def __init__(self, target, root, _id):
|
||||||
@ -47,28 +53,80 @@ class ThermalZone(object):
|
|||||||
self.name = 'thermal_zone' + _id
|
self.name = 'thermal_zone' + _id
|
||||||
self.path = target.path.join(root, self.name)
|
self.path = target.path.join(root, self.name)
|
||||||
self.trip_points = {}
|
self.trip_points = {}
|
||||||
|
self.type = self.target.read_value(self.target.path.join(self.path, 'type'))
|
||||||
|
|
||||||
for entry in self.target.list_directory(self.path):
|
for entry in self.target.list_directory(self.path, as_root=target.is_rooted):
|
||||||
re_match = re.match('^trip_point_([0-9]+)_temp', entry)
|
re_match = re.match('^trip_point_([0-9]+)_temp', entry)
|
||||||
if re_match is not None:
|
if re_match is not None:
|
||||||
self.add_trip_point(re_match.group(1))
|
self._add_trip_point(re_match.group(1))
|
||||||
|
|
||||||
def add_trip_point(self, _id):
|
def _add_trip_point(self, _id):
|
||||||
self.trip_points[int(_id)] = TripPoint(self, _id)
|
self.trip_points[int(_id)] = TripPoint(self, _id)
|
||||||
|
|
||||||
def is_enabled(self):
|
@asyn.asyncf
|
||||||
|
async def is_enabled(self):
|
||||||
"""Returns a boolean representing the 'mode' of the thermal zone"""
|
"""Returns a boolean representing the 'mode' of the thermal zone"""
|
||||||
value = self.target.read_value(self.target.path.join(self.path, 'mode'))
|
value = await self.target.read_value.asyn(self.target.path.join(self.path, 'mode'))
|
||||||
return value == 'enabled'
|
return value == 'enabled'
|
||||||
|
|
||||||
def set_enabled(self, enabled=True):
|
@asyn.asyncf
|
||||||
|
async def set_enabled(self, enabled=True):
|
||||||
value = 'enabled' if enabled else 'disabled'
|
value = 'enabled' if enabled else 'disabled'
|
||||||
self.target.write_value(self.target.path.join(self.path, 'mode'), value)
|
await self.target.write_value.asyn(self.target.path.join(self.path, 'mode'), value)
|
||||||
|
|
||||||
def get_temperature(self):
|
@asyn.asyncf
|
||||||
|
async def get_temperature(self):
|
||||||
"""Returns the temperature of the thermal zone"""
|
"""Returns the temperature of the thermal zone"""
|
||||||
temp_file = self.target.path.join(self.path, 'temp')
|
sysfs_temperature_file = self.target.path.join(self.path, 'temp')
|
||||||
return self.target.read_int(temp_file)
|
return await self.target.read_int.asyn(sysfs_temperature_file)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def get_policy(self):
|
||||||
|
"""Returns the policy of the thermal zone"""
|
||||||
|
temp_file = self.target.path.join(self.path, 'policy')
|
||||||
|
return await self.target.read_value.asyn(temp_file)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def set_policy(self, policy):
|
||||||
|
"""
|
||||||
|
Sets the policy of the thermal zone
|
||||||
|
|
||||||
|
:params policy: Thermal governor name
|
||||||
|
:type policy: str
|
||||||
|
"""
|
||||||
|
await self.target.write_value.asyn(self.target.path.join(self.path, 'policy'), policy)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def get_offset(self):
|
||||||
|
"""Returns the temperature offset of the thermal zone"""
|
||||||
|
offset_file = self.target.path.join(self.path, 'offset')
|
||||||
|
return await self.target.read_value.asyn(offset_file)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def set_offset(self, offset):
|
||||||
|
"""
|
||||||
|
Sets the temperature offset in milli-degrees of the thermal zone
|
||||||
|
|
||||||
|
:params offset: Temperature offset in milli-degrees
|
||||||
|
:type policy: int
|
||||||
|
"""
|
||||||
|
await self.target.write_value.asyn(self.target.path.join(self.path, 'offset'), policy)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def set_emul_temp(self, offset):
|
||||||
|
"""
|
||||||
|
Sets the emulated temperature in milli-degrees of the thermal zone
|
||||||
|
|
||||||
|
:params offset: Emulated temperature in milli-degrees
|
||||||
|
:type policy: int
|
||||||
|
"""
|
||||||
|
await self.target.write_value.asyn(self.target.path.join(self.path, 'emul_temp'), policy)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def get_available_policies(self):
|
||||||
|
"""Returns the policies available for the thermal zone"""
|
||||||
|
temp_file = self.target.path.join(self.path, 'available_policies')
|
||||||
|
return await self.target.read_value.asyn(temp_file)
|
||||||
|
|
||||||
class ThermalModule(Module):
|
class ThermalModule(Module):
|
||||||
name = 'thermal'
|
name = 'thermal'
|
||||||
@ -83,22 +141,57 @@ class ThermalModule(Module):
|
|||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
super(ThermalModule, self).__init__(target)
|
super(ThermalModule, self).__init__(target)
|
||||||
|
|
||||||
|
self.logger = logging.getLogger(self.name)
|
||||||
|
self.logger.debug('Initialized [%s] module', self.name)
|
||||||
|
|
||||||
self.zones = {}
|
self.zones = {}
|
||||||
self.cdevs = []
|
self.cdevs = []
|
||||||
|
|
||||||
for entry in target.list_directory(self.thermal_root):
|
for entry in target.list_directory(self.thermal_root):
|
||||||
re_match = re.match('^(thermal_zone|cooling_device)([0-9]+)', entry)
|
re_match = re.match('^(thermal_zone|cooling_device)([0-9]+)', entry)
|
||||||
|
if not re_match:
|
||||||
|
self.logger.warning('unknown thermal entry: %s', entry)
|
||||||
|
continue
|
||||||
|
|
||||||
if re_match.group(1) == 'thermal_zone':
|
if re_match.group(1) == 'thermal_zone':
|
||||||
self.add_thermal_zone(re_match.group(2))
|
self._add_thermal_zone(re_match.group(2))
|
||||||
elif re_match.group(1) == 'cooling_device':
|
elif re_match.group(1) == 'cooling_device':
|
||||||
# TODO
|
# TODO
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def add_thermal_zone(self, _id):
|
def _add_thermal_zone(self, _id):
|
||||||
self.zones[int(_id)] = ThermalZone(self.target, self.thermal_root, _id)
|
self.zones[int(_id)] = ThermalZone(self.target, self.thermal_root, _id)
|
||||||
|
|
||||||
def disable_all_zones(self):
|
def disable_all_zones(self):
|
||||||
"""Disables all the thermal zones in the target"""
|
"""Disables all the thermal zones in the target"""
|
||||||
for zone in self.zones.values():
|
for zone in self.zones.values():
|
||||||
zone.set_enabled(False)
|
zone.set_enabled(False)
|
||||||
|
|
||||||
|
@asyn.asyncf
|
||||||
|
async def get_all_temperatures(self, error='raise'):
|
||||||
|
"""
|
||||||
|
Returns dictionary with current reading of all thermal zones.
|
||||||
|
|
||||||
|
:params error: Sensor read error handling (raise or ignore)
|
||||||
|
:type error: str
|
||||||
|
|
||||||
|
:returns: a dictionary in the form: {tz_type:temperature}
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def get_temperature_noexcep(item):
|
||||||
|
tzid, tz = item
|
||||||
|
try:
|
||||||
|
temperature = await tz.get_temperature.asyn()
|
||||||
|
except TargetStableCalledProcessError as e:
|
||||||
|
if error == 'raise':
|
||||||
|
raise e
|
||||||
|
elif error == 'ignore':
|
||||||
|
self.logger.warning(f'Skipping thermal_zone_id={tzid} thermal_zone_type={tz.type} error="{e}"')
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown error parameter value: {error}')
|
||||||
|
return temperature
|
||||||
|
|
||||||
|
tz_temps = await self.target.async_manager.map_concurrently(get_temperature_noexcep, self.zones.items())
|
||||||
|
|
||||||
|
return {tz.type: temperature for (tzid, tz), temperature in tz_temps.items() if temperature is not None}
|
||||||
|
@ -20,7 +20,8 @@ import shutil
|
|||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
|
|
||||||
from devlib.module import HardRestModule, BootModule, FlashModule
|
from devlib.module import HardRestModule, BootModule, FlashModule
|
||||||
from devlib.exception import TargetError, HostError
|
from devlib.exception import TargetError, TargetStableError, HostError
|
||||||
|
from devlib.utils.misc import safe_extract
|
||||||
from devlib.utils.serial_port import open_serial_connection, pulse_dtr, write_characters
|
from devlib.utils.serial_port import open_serial_connection, pulse_dtr, write_characters
|
||||||
from devlib.utils.uefi import UefiMenu, UefiConfig
|
from devlib.utils.uefi import UefiMenu, UefiConfig
|
||||||
from devlib.utils.uboot import UbootMenu
|
from devlib.utils.uboot import UbootMenu
|
||||||
@ -89,7 +90,7 @@ class VexpressReboottxtHardReset(HardRestModule):
|
|||||||
try:
|
try:
|
||||||
if self.target.is_connected:
|
if self.target.is_connected:
|
||||||
self.target.execute('sync')
|
self.target.execute('sync')
|
||||||
except TargetError:
|
except (TargetError, CalledProcessError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not os.path.exists(self.path):
|
if not os.path.exists(self.path):
|
||||||
@ -130,7 +131,7 @@ class VexpressBootModule(BootModule):
|
|||||||
init_dtr=0) as tty:
|
init_dtr=0) as tty:
|
||||||
self.get_through_early_boot(tty)
|
self.get_through_early_boot(tty)
|
||||||
self.perform_boot_sequence(tty)
|
self.perform_boot_sequence(tty)
|
||||||
self.wait_for_android_prompt(tty)
|
self.wait_for_shell_prompt(tty)
|
||||||
|
|
||||||
def perform_boot_sequence(self, tty):
|
def perform_boot_sequence(self, tty):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
@ -159,8 +160,8 @@ class VexpressBootModule(BootModule):
|
|||||||
menu.wait(timeout=self.timeout)
|
menu.wait(timeout=self.timeout)
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
def wait_for_android_prompt(self, tty):
|
def wait_for_shell_prompt(self, tty):
|
||||||
self.logger.debug('Waiting for the Android prompt.')
|
self.logger.debug('Waiting for the shell prompt.')
|
||||||
tty.expect(self.target.shell_prompt, timeout=self.timeout)
|
tty.expect(self.target.shell_prompt, timeout=self.timeout)
|
||||||
# This delay is needed to allow the platform some time to finish
|
# This delay is needed to allow the platform some time to finish
|
||||||
# initilizing; querying the ip address too early from connect() may
|
# initilizing; querying the ip address too early from connect() may
|
||||||
@ -209,6 +210,7 @@ class VexpressUefiShellBoot(VexpressBootModule):
|
|||||||
|
|
||||||
name = 'vexpress-uefi-shell'
|
name = 'vexpress-uefi-shell'
|
||||||
|
|
||||||
|
# pylint: disable=keyword-arg-before-vararg
|
||||||
def __init__(self, target, uefi_entry='^Shell$',
|
def __init__(self, target, uefi_entry='^Shell$',
|
||||||
efi_shell_prompt='Shell>',
|
efi_shell_prompt='Shell>',
|
||||||
image='kernel', bootargs=None,
|
image='kernel', bootargs=None,
|
||||||
@ -224,7 +226,7 @@ class VexpressUefiShellBoot(VexpressBootModule):
|
|||||||
try:
|
try:
|
||||||
menu.select(self.uefi_entry)
|
menu.select(self.uefi_entry)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
raise TargetError('Did not see "{}" UEFI entry.'.format(self.uefi_entry))
|
raise TargetStableError('Did not see "{}" UEFI entry.'.format(self.uefi_entry))
|
||||||
tty.expect(self.efi_shell_prompt, timeout=self.timeout)
|
tty.expect(self.efi_shell_prompt, timeout=self.timeout)
|
||||||
if self.bootargs:
|
if self.bootargs:
|
||||||
tty.sendline('') # stop default boot
|
tty.sendline('') # stop default boot
|
||||||
@ -239,6 +241,7 @@ class VexpressUBoot(VexpressBootModule):
|
|||||||
|
|
||||||
name = 'vexpress-u-boot'
|
name = 'vexpress-u-boot'
|
||||||
|
|
||||||
|
# pylint: disable=keyword-arg-before-vararg
|
||||||
def __init__(self, target, env=None,
|
def __init__(self, target, env=None,
|
||||||
*args, **kwargs):
|
*args, **kwargs):
|
||||||
super(VexpressUBoot, self).__init__(target, *args, **kwargs)
|
super(VexpressUBoot, self).__init__(target, *args, **kwargs)
|
||||||
@ -260,6 +263,7 @@ class VexpressBootmon(VexpressBootModule):
|
|||||||
|
|
||||||
name = 'vexpress-bootmon'
|
name = 'vexpress-bootmon'
|
||||||
|
|
||||||
|
# pylint: disable=keyword-arg-before-vararg
|
||||||
def __init__(self, target,
|
def __init__(self, target,
|
||||||
image, fdt, initrd, bootargs,
|
image, fdt, initrd, bootargs,
|
||||||
uses_bootscript=False,
|
uses_bootscript=False,
|
||||||
@ -282,11 +286,11 @@ class VexpressBootmon(VexpressBootModule):
|
|||||||
with open_serial_connection(port=self.port,
|
with open_serial_connection(port=self.port,
|
||||||
baudrate=self.baudrate,
|
baudrate=self.baudrate,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
init_dtr=0) as tty:
|
init_dtr=0) as tty_conn:
|
||||||
write_characters(tty, 'fl linux fdt {}'.format(self.fdt))
|
write_characters(tty_conn, 'fl linux fdt {}'.format(self.fdt))
|
||||||
write_characters(tty, 'fl linux initrd {}'.format(self.initrd))
|
write_characters(tty_conn, 'fl linux initrd {}'.format(self.initrd))
|
||||||
write_characters(tty, 'fl linux boot {} {}'.format(self.image,
|
write_characters(tty_conn, 'fl linux boot {} {}'.format(self.image,
|
||||||
self.bootargs))
|
self.bootargs))
|
||||||
|
|
||||||
|
|
||||||
class VersatileExpressFlashModule(FlashModule):
|
class VersatileExpressFlashModule(FlashModule):
|
||||||
@ -322,15 +326,16 @@ class VersatileExpressFlashModule(FlashModule):
|
|||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.short_delay = short_delay
|
self.short_delay = short_delay
|
||||||
|
|
||||||
def __call__(self, image_bundle=None, images=None, bootargs=None):
|
def __call__(self, image_bundle=None, images=None, bootargs=None, connect=True):
|
||||||
self.target.hard_reset()
|
self.target.hard_reset()
|
||||||
with open_serial_connection(port=self.target.platform.serial_port,
|
with open_serial_connection(port=self.target.platform.serial_port,
|
||||||
baudrate=self.target.platform.baudrate,
|
baudrate=self.target.platform.baudrate,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
init_dtr=0) as tty:
|
init_dtr=0) as tty:
|
||||||
|
# pylint: disable=no-member
|
||||||
i = tty.expect([self.mcc_prompt, AUTOSTART_MESSAGE, OLD_AUTOSTART_MESSAGE])
|
i = tty.expect([self.mcc_prompt, AUTOSTART_MESSAGE, OLD_AUTOSTART_MESSAGE])
|
||||||
if i:
|
if i:
|
||||||
tty.sendline('')
|
tty.sendline('') # pylint: disable=no-member
|
||||||
wait_for_vemsd(self.vemsd_mount, tty, self.mcc_prompt, self.short_delay)
|
wait_for_vemsd(self.vemsd_mount, tty, self.mcc_prompt, self.short_delay)
|
||||||
try:
|
try:
|
||||||
if image_bundle:
|
if image_bundle:
|
||||||
@ -340,16 +345,17 @@ class VersatileExpressFlashModule(FlashModule):
|
|||||||
os.system('sync')
|
os.system('sync')
|
||||||
except (IOError, OSError) as e:
|
except (IOError, OSError) as e:
|
||||||
msg = 'Could not deploy images to {}; got: {}'
|
msg = 'Could not deploy images to {}; got: {}'
|
||||||
raise TargetError(msg.format(self.vemsd_mount, e))
|
raise TargetStableError(msg.format(self.vemsd_mount, e))
|
||||||
self.target.boot()
|
self.target.boot()
|
||||||
self.target.connect(timeout=30)
|
if connect:
|
||||||
|
self.target.connect(timeout=30)
|
||||||
|
|
||||||
def _deploy_image_bundle(self, bundle):
|
def _deploy_image_bundle(self, bundle):
|
||||||
self.logger.debug('Validating {}'.format(bundle))
|
self.logger.debug('Validating {}'.format(bundle))
|
||||||
validate_image_bundle(bundle)
|
validate_image_bundle(bundle)
|
||||||
self.logger.debug('Extracting {} into {}...'.format(bundle, self.vemsd_mount))
|
self.logger.debug('Extracting {} into {}...'.format(bundle, self.vemsd_mount))
|
||||||
with tarfile.open(bundle) as tar:
|
with tarfile.open(bundle) as tar:
|
||||||
tar.extractall(self.vemsd_mount)
|
safe_extract(tar, self.vemsd_mount)
|
||||||
|
|
||||||
def _overlay_images(self, images):
|
def _overlay_images(self, images):
|
||||||
for dest, src in images.items():
|
for dest, src in images.items():
|
||||||
@ -386,5 +392,4 @@ def wait_for_vemsd(vemsd_mount, tty, mcc_prompt=DEFAULT_MCC_PROMPT, short_delay=
|
|||||||
time.sleep(short_delay * 3)
|
time.sleep(short_delay * 3)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return
|
return
|
||||||
raise TargetError('Could not mount {}'.format(vemsd_mount))
|
raise TargetStableError('Could not mount {}'.format(vemsd_mount))
|
||||||
|
|
||||||
|
@ -78,7 +78,16 @@ class Platform(object):
|
|||||||
|
|
||||||
def _set_model_from_target(self, target):
|
def _set_model_from_target(self, target):
|
||||||
if target.os == 'android':
|
if target.os == 'android':
|
||||||
self.model = target.getprop('ro.product.model')
|
try:
|
||||||
|
self.model = target.getprop(prop='ro.product.device')
|
||||||
|
except KeyError:
|
||||||
|
self.model = target.getprop('ro.product.model')
|
||||||
|
elif target.file_exists("/proc/device-tree/model"):
|
||||||
|
# There is currently no better way to do this cross platform.
|
||||||
|
# ARM does not have dmidecode
|
||||||
|
raw_model = target.execute("cat /proc/device-tree/model")
|
||||||
|
device_model_to_return = '_'.join(raw_model.split()[:2])
|
||||||
|
return device_model_to_return.rstrip(' \t\r\n\0')
|
||||||
elif target.is_rooted:
|
elif target.is_rooted:
|
||||||
try:
|
try:
|
||||||
self.model = target.execute('dmidecode -s system-version',
|
self.model = target.execute('dmidecode -s system-version',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2015-2018 ARM Limited
|
# Copyright 2015-2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,17 +12,16 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from __future__ import division
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import pexpect
|
import pexpect
|
||||||
|
|
||||||
from devlib.platform import Platform
|
from devlib.exception import HostError, TargetTransientError
|
||||||
from devlib.instrument import Instrument, InstrumentChannel, MeasurementsCsv, Measurement, CONTINUOUS, INSTANTANEOUS
|
|
||||||
from devlib.exception import TargetError, HostError
|
|
||||||
from devlib.host import PACKAGE_BIN_DIRECTORY
|
from devlib.host import PACKAGE_BIN_DIRECTORY
|
||||||
|
from devlib.instrument import (Instrument, InstrumentChannel, MeasurementsCsv,
|
||||||
|
Measurement, CONTINUOUS, INSTANTANEOUS)
|
||||||
|
from devlib.platform import Platform
|
||||||
from devlib.utils.csvutil import csvreader, csvwriter
|
from devlib.utils.csvutil import csvreader, csvwriter
|
||||||
from devlib.utils.serial_port import open_serial_connection
|
from devlib.utils.serial_port import open_serial_connection
|
||||||
|
|
||||||
@ -89,9 +88,6 @@ class VersatileExpressPlatform(Platform):
|
|||||||
def _init_android_target(self, target):
|
def _init_android_target(self, target):
|
||||||
if target.connection_settings.get('device') is None:
|
if target.connection_settings.get('device') is None:
|
||||||
addr = self._get_target_ip_address(target)
|
addr = self._get_target_ip_address(target)
|
||||||
if sys.version_info[0] == 3:
|
|
||||||
# Convert bytes to string for Python3 compatibility
|
|
||||||
addr = addr.decode("utf-8")
|
|
||||||
target.connection_settings['device'] = addr + ':5555'
|
target.connection_settings['device'] = addr + ':5555'
|
||||||
|
|
||||||
def _init_linux_target(self, target):
|
def _init_linux_target(self, target):
|
||||||
@ -99,6 +95,7 @@ class VersatileExpressPlatform(Platform):
|
|||||||
addr = self._get_target_ip_address(target)
|
addr = self._get_target_ip_address(target)
|
||||||
target.connection_settings['host'] = addr
|
target.connection_settings['host'] = addr
|
||||||
|
|
||||||
|
# pylint: disable=no-member
|
||||||
def _get_target_ip_address(self, target):
|
def _get_target_ip_address(self, target):
|
||||||
with open_serial_connection(port=self.serial_port,
|
with open_serial_connection(port=self.serial_port,
|
||||||
baudrate=self.baudrate,
|
baudrate=self.baudrate,
|
||||||
@ -106,7 +103,7 @@ class VersatileExpressPlatform(Platform):
|
|||||||
init_dtr=0) as tty:
|
init_dtr=0) as tty:
|
||||||
tty.sendline('su') # this is, apprently, required to query network device
|
tty.sendline('su') # this is, apprently, required to query network device
|
||||||
# info by name on recent Juno builds...
|
# info by name on recent Juno builds...
|
||||||
self.logger.debug('Waiting for the Android shell prompt.')
|
self.logger.debug('Waiting for the shell prompt.')
|
||||||
tty.expect(target.shell_prompt)
|
tty.expect(target.shell_prompt)
|
||||||
|
|
||||||
self.logger.debug('Waiting for IP address...')
|
self.logger.debug('Waiting for IP address...')
|
||||||
@ -117,11 +114,11 @@ class VersatileExpressPlatform(Platform):
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
try:
|
try:
|
||||||
tty.expect(r'inet ([1-9]\d*.\d+.\d+.\d+)', timeout=10)
|
tty.expect(r'inet ([1-9]\d*.\d+.\d+.\d+)', timeout=10)
|
||||||
return tty.match.group(1)
|
return tty.match.group(1).decode('utf-8')
|
||||||
except pexpect.TIMEOUT:
|
except pexpect.TIMEOUT:
|
||||||
pass # We have our own timeout -- see below.
|
pass # We have our own timeout -- see below.
|
||||||
if (time.time() - wait_start_time) > self.ready_timeout:
|
if (time.time() - wait_start_time) > self.ready_timeout:
|
||||||
raise TargetError('Could not acquire IP address.')
|
raise TargetTransientError('Could not acquire IP address.')
|
||||||
finally:
|
finally:
|
||||||
tty.sendline('exit') # exit shell created by "su" call at the start
|
tty.sendline('exit') # exit shell created by "su" call at the start
|
||||||
|
|
||||||
@ -250,7 +247,7 @@ class JunoEnergyInstrument(Instrument):
|
|||||||
self.command = '{} -o {}'.format(self.binary, self.on_target_file)
|
self.command = '{} -o {}'.format(self.binary, self.on_target_file)
|
||||||
self.command2 = '{}'.format(self.binary)
|
self.command2 = '{}'.format(self.binary)
|
||||||
|
|
||||||
def setup(self):
|
def setup(self): # pylint: disable=arguments-differ
|
||||||
self.binary = self.target.install(os.path.join(PACKAGE_BIN_DIRECTORY,
|
self.binary = self.target.install(os.path.join(PACKAGE_BIN_DIRECTORY,
|
||||||
self.target.abi, self.binname))
|
self.target.abi, self.binname))
|
||||||
self.command = '{} -o {}'.format(self.binary, self.on_target_file)
|
self.command = '{} -o {}'.format(self.binary, self.on_target_file)
|
||||||
@ -266,6 +263,7 @@ class JunoEnergyInstrument(Instrument):
|
|||||||
def stop(self):
|
def stop(self):
|
||||||
self.target.killall(self.binname, signal='TERM', as_root=True)
|
self.target.killall(self.binname, signal='TERM', as_root=True)
|
||||||
|
|
||||||
|
# pylint: disable=arguments-differ
|
||||||
def get_data(self, output_file):
|
def get_data(self, output_file):
|
||||||
temp_file = tempfile.mktemp()
|
temp_file = tempfile.mktemp()
|
||||||
self.target.pull(self.on_target_file, temp_file)
|
self.target.pull(self.on_target_file, temp_file)
|
||||||
@ -296,10 +294,9 @@ class JunoEnergyInstrument(Instrument):
|
|||||||
result = []
|
result = []
|
||||||
output = self.target.execute(self.command2).split()
|
output = self.target.execute(self.command2).split()
|
||||||
with csvreader(output) as reader:
|
with csvreader(output) as reader:
|
||||||
headings=next(reader)
|
headings = next(reader)
|
||||||
values = next(reader)
|
values = next(reader)
|
||||||
for chan in self.active_channels:
|
for chan in self.active_channels:
|
||||||
value = values[headings.index(chan.name)]
|
value = values[headings.index(chan.name)]
|
||||||
result.append(Measurement(value, chan))
|
result.append(Measurement(value, chan))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
|
import shlex
|
||||||
|
from shlex import quote
|
||||||
|
|
||||||
from devlib.exception import TargetError
|
from devlib.exception import TargetStableError
|
||||||
from devlib.host import PACKAGE_BIN_DIRECTORY
|
from devlib.host import PACKAGE_BIN_DIRECTORY
|
||||||
from devlib.platform import Platform
|
from devlib.platform import Platform
|
||||||
from devlib.utils.ssh import AndroidGem5Connection, LinuxGem5Connection
|
from devlib.utils.ssh import AndroidGem5Connection, LinuxGem5Connection
|
||||||
@ -55,7 +56,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
self.stdout_file = None
|
self.stdout_file = None
|
||||||
self.stderr_file = None
|
self.stderr_file = None
|
||||||
self.stderr_filename = None
|
self.stderr_filename = None
|
||||||
if self.gem5_port is None:
|
if self.gem5_port is None: # pylint: disable=simplifiable-if-statement
|
||||||
# Allows devlib to pick up already running simulations
|
# Allows devlib to pick up already running simulations
|
||||||
self.start_gem5_simulation = True
|
self.start_gem5_simulation = True
|
||||||
else:
|
else:
|
||||||
@ -87,12 +88,12 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
Check if the command to start gem5 makes sense
|
Check if the command to start gem5 makes sense
|
||||||
"""
|
"""
|
||||||
if self.gem5args_binary is None:
|
if self.gem5args_binary is None:
|
||||||
raise TargetError('Please specify a gem5 binary.')
|
raise TargetStableError('Please specify a gem5 binary.')
|
||||||
if self.gem5args_args is None:
|
if self.gem5args_args is None:
|
||||||
raise TargetError('Please specify the arguments passed on to gem5.')
|
raise TargetStableError('Please specify the arguments passed on to gem5.')
|
||||||
self.gem5args_virtio = str(self.gem5args_virtio).format(self.gem5_interact_dir)
|
self.gem5args_virtio = str(self.gem5args_virtio).format(self.gem5_interact_dir)
|
||||||
if self.gem5args_virtio is None:
|
if self.gem5args_virtio is None:
|
||||||
raise TargetError('Please specify arguments needed for virtIO.')
|
raise TargetStableError('Please specify arguments needed for virtIO.')
|
||||||
|
|
||||||
def _start_interaction_gem5(self):
|
def _start_interaction_gem5(self):
|
||||||
"""
|
"""
|
||||||
@ -111,7 +112,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
if not os.path.exists(self.stats_directory):
|
if not os.path.exists(self.stats_directory):
|
||||||
os.mkdir(self.stats_directory)
|
os.mkdir(self.stats_directory)
|
||||||
if os.path.exists(self.gem5_out_dir):
|
if os.path.exists(self.gem5_out_dir):
|
||||||
raise TargetError("The gem5 stats directory {} already "
|
raise TargetStableError("The gem5 stats directory {} already "
|
||||||
"exists.".format(self.gem5_out_dir))
|
"exists.".format(self.gem5_out_dir))
|
||||||
else:
|
else:
|
||||||
os.mkdir(self.gem5_out_dir)
|
os.mkdir(self.gem5_out_dir)
|
||||||
@ -130,11 +131,11 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
self.logger.info("Starting the gem5 simulator")
|
self.logger.info("Starting the gem5 simulator")
|
||||||
|
|
||||||
command_line = "{} --outdir={} {} {}".format(self.gem5args_binary,
|
command_line = "{} --outdir={} {} {}".format(self.gem5args_binary,
|
||||||
self.gem5_out_dir,
|
quote(self.gem5_out_dir),
|
||||||
self.gem5args_args,
|
self.gem5args_args,
|
||||||
self.gem5args_virtio)
|
self.gem5args_virtio)
|
||||||
self.logger.debug("gem5 command line: {}".format(command_line))
|
self.logger.debug("gem5 command line: {}".format(command_line))
|
||||||
self.gem5 = subprocess.Popen(command_line.split(),
|
self.gem5 = subprocess.Popen(shlex.split(command_line),
|
||||||
stdout=self.stdout_file,
|
stdout=self.stdout_file,
|
||||||
stderr=self.stderr_file)
|
stderr=self.stderr_file)
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
e.g. pid, input directory etc
|
e.g. pid, input directory etc
|
||||||
"""
|
"""
|
||||||
self.logger("This functionality is not yet implemented")
|
self.logger("This functionality is not yet implemented")
|
||||||
raise TargetError()
|
raise TargetStableError()
|
||||||
|
|
||||||
def _intercept_telnet_port(self):
|
def _intercept_telnet_port(self):
|
||||||
"""
|
"""
|
||||||
@ -162,13 +163,13 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if self.gem5 is None:
|
if self.gem5 is None:
|
||||||
raise TargetError('The platform has no gem5 simulation! '
|
raise TargetStableError('The platform has no gem5 simulation! '
|
||||||
'Something went wrong')
|
'Something went wrong')
|
||||||
while self.gem5_port is None:
|
while self.gem5_port is None:
|
||||||
# Check that gem5 is running!
|
# Check that gem5 is running!
|
||||||
if self.gem5.poll():
|
if self.gem5.poll():
|
||||||
message = "The gem5 process has crashed with error code {}!\n\tPlease see {} for details."
|
message = "The gem5 process has crashed with error code {}!\n\tPlease see {} for details."
|
||||||
raise TargetError(message.format(self.gem5.poll(), self.stderr_file.name))
|
raise TargetStableError(message.format(self.gem5.poll(), self.stderr_file.name))
|
||||||
|
|
||||||
# Open the stderr file
|
# Open the stderr file
|
||||||
with open(self.stderr_filename, 'r') as f:
|
with open(self.stderr_filename, 'r') as f:
|
||||||
@ -186,7 +187,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
# Check if the sockets are not disabled
|
# Check if the sockets are not disabled
|
||||||
m = re.search(r"Sockets disabled, not accepting terminal connections", line)
|
m = re.search(r"Sockets disabled, not accepting terminal connections", line)
|
||||||
if m:
|
if m:
|
||||||
raise TargetError("The sockets have been disabled!"
|
raise TargetStableError("The sockets have been disabled!"
|
||||||
"Pass --listener-mode=on to gem5")
|
"Pass --listener-mode=on to gem5")
|
||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
@ -234,6 +235,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
# Call the general update_from_target implementation
|
# Call the general update_from_target implementation
|
||||||
super(Gem5SimulationPlatform, self).update_from_target(target)
|
super(Gem5SimulationPlatform, self).update_from_target(target)
|
||||||
|
|
||||||
|
|
||||||
def gem5_capture_screen(self, filepath):
|
def gem5_capture_screen(self, filepath):
|
||||||
file_list = os.listdir(self.gem5_out_dir)
|
file_list = os.listdir(self.gem5_out_dir)
|
||||||
screen_caps = []
|
screen_caps = []
|
||||||
@ -243,6 +245,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
|
|
||||||
if '{ts}' in filepath:
|
if '{ts}' in filepath:
|
||||||
cmd = '{} date -u -Iseconds'
|
cmd = '{} date -u -Iseconds'
|
||||||
|
# pylint: disable=no-member
|
||||||
ts = self.target.execute(cmd.format(self.target.busybox)).strip()
|
ts = self.target.execute(cmd.format(self.target.busybox)).strip()
|
||||||
filepath = filepath.format(ts=ts)
|
filepath = filepath.format(ts=ts)
|
||||||
|
|
||||||
@ -258,6 +261,7 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
im.save(temp_image, "PNG")
|
im.save(temp_image, "PNG")
|
||||||
shutil.copy(temp_image, filepath)
|
shutil.copy(temp_image, filepath)
|
||||||
os.remove(temp_image)
|
os.remove(temp_image)
|
||||||
|
# pylint: disable=undefined-variable
|
||||||
gem5_logger.info("capture_screen: using gem5 screencap")
|
gem5_logger.info("capture_screen: using gem5 screencap")
|
||||||
successful_capture = True
|
successful_capture = True
|
||||||
|
|
||||||
@ -266,12 +270,14 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
|
|
||||||
return successful_capture
|
return successful_capture
|
||||||
|
|
||||||
|
# pylint: disable=no-self-use
|
||||||
def _deploy_m5(self, target):
|
def _deploy_m5(self, target):
|
||||||
# m5 is not yet installed so install it
|
# m5 is not yet installed so install it
|
||||||
host_executable = os.path.join(PACKAGE_BIN_DIRECTORY,
|
host_executable = os.path.join(PACKAGE_BIN_DIRECTORY,
|
||||||
target.abi, 'm5')
|
target.abi, 'm5')
|
||||||
return target.install(host_executable)
|
return target.install(host_executable)
|
||||||
|
|
||||||
|
# pylint: disable=no-self-use
|
||||||
def _resize_shell(self, target):
|
def _resize_shell(self, target):
|
||||||
"""
|
"""
|
||||||
Resize the shell to avoid line wrapping issues.
|
Resize the shell to avoid line wrapping issues.
|
||||||
@ -282,18 +288,16 @@ class Gem5SimulationPlatform(Platform):
|
|||||||
target.execute('reset', check_exit_code=False)
|
target.execute('reset', check_exit_code=False)
|
||||||
|
|
||||||
# Methods that will be monkey-patched onto the target
|
# Methods that will be monkey-patched onto the target
|
||||||
def _overwritten_reset(self):
|
def _overwritten_reset(self): # pylint: disable=unused-argument
|
||||||
raise TargetError('Resetting is not allowed on gem5 platforms!')
|
raise TargetStableError('Resetting is not allowed on gem5 platforms!')
|
||||||
|
|
||||||
def _overwritten_reboot(self):
|
def _overwritten_reboot(self): # pylint: disable=unused-argument
|
||||||
raise TargetError('Rebooting is not allowed on gem5 platforms!')
|
raise TargetStableError('Rebooting is not allowed on gem5 platforms!')
|
||||||
|
|
||||||
def _overwritten_capture_screen(self, filepath):
|
def _overwritten_capture_screen(self, filepath):
|
||||||
connection_screencapped = self.platform.gem5_capture_screen(filepath)
|
connection_screencapped = self.platform.gem5_capture_screen(filepath)
|
||||||
if connection_screencapped == False:
|
if not connection_screencapped:
|
||||||
# The connection was not able to capture the screen so use the target
|
# The connection was not able to capture the screen so use the target
|
||||||
# implementation
|
# implementation
|
||||||
self.logger.debug('{} was not able to screen cap, using the original target implementation'.format(self.platform.__class__.__name__))
|
self.logger.debug('{} was not able to screen cap, using the original target implementation'.format(self.platform.__class__.__name__))
|
||||||
self.target_impl_capture_screen(filepath)
|
self.target_impl_capture_screen(filepath)
|
||||||
|
|
||||||
|
|
||||||
|
2557
devlib/target.py
2557
devlib/target.py
File diff suppressed because it is too large
Load Diff
@ -1,35 +0,0 @@
|
|||||||
# Copyright 2015 ARM Limited
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
|
|
||||||
class TraceCollector(object):
|
|
||||||
|
|
||||||
def __init__(self, target):
|
|
||||||
self.target = target
|
|
||||||
self.logger = logging.getLogger(self.__class__.__name__)
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_trace(self, outfile):
|
|
||||||
pass
|
|
@ -1,350 +0,0 @@
|
|||||||
# Copyright 2015-2018 ARM Limited
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from devlib.trace import TraceCollector
|
|
||||||
from devlib.host import PACKAGE_BIN_DIRECTORY
|
|
||||||
from devlib.exception import TargetError, HostError
|
|
||||||
from devlib.utils.misc import check_output, which
|
|
||||||
|
|
||||||
|
|
||||||
TRACE_MARKER_START = 'TRACE_MARKER_START'
|
|
||||||
TRACE_MARKER_STOP = 'TRACE_MARKER_STOP'
|
|
||||||
OUTPUT_TRACE_FILE = 'trace.dat'
|
|
||||||
OUTPUT_PROFILE_FILE = 'trace_stat.dat'
|
|
||||||
DEFAULT_EVENTS = [
|
|
||||||
'cpu_frequency',
|
|
||||||
'cpu_idle',
|
|
||||||
'sched_migrate_task',
|
|
||||||
'sched_process_exec',
|
|
||||||
'sched_process_fork',
|
|
||||||
'sched_stat_iowait',
|
|
||||||
'sched_switch',
|
|
||||||
'sched_wakeup',
|
|
||||||
'sched_wakeup_new',
|
|
||||||
]
|
|
||||||
TIMEOUT = 180
|
|
||||||
|
|
||||||
# Regexps for parsing of function profiling data
|
|
||||||
CPU_RE = re.compile(r' Function \(CPU([0-9]+)\)')
|
|
||||||
STATS_RE = re.compile(r'([^ ]*) +([0-9]+) +([0-9.]+) us +([0-9.]+) us +([0-9.]+) us')
|
|
||||||
|
|
||||||
class FtraceCollector(TraceCollector):
|
|
||||||
|
|
||||||
def __init__(self, target,
|
|
||||||
events=None,
|
|
||||||
functions=None,
|
|
||||||
buffer_size=None,
|
|
||||||
buffer_size_step=1000,
|
|
||||||
tracing_path='/sys/kernel/debug/tracing',
|
|
||||||
automark=True,
|
|
||||||
autoreport=True,
|
|
||||||
autoview=False,
|
|
||||||
no_install=False,
|
|
||||||
strict=False,
|
|
||||||
report_on_target=False,
|
|
||||||
):
|
|
||||||
super(FtraceCollector, self).__init__(target)
|
|
||||||
self.events = events if events is not None else DEFAULT_EVENTS
|
|
||||||
self.functions = functions
|
|
||||||
self.buffer_size = buffer_size
|
|
||||||
self.buffer_size_step = buffer_size_step
|
|
||||||
self.tracing_path = tracing_path
|
|
||||||
self.automark = automark
|
|
||||||
self.autoreport = autoreport
|
|
||||||
self.autoview = autoview
|
|
||||||
self.report_on_target = report_on_target
|
|
||||||
self.target_output_file = target.path.join(self.target.working_directory, OUTPUT_TRACE_FILE)
|
|
||||||
text_file_name = target.path.splitext(OUTPUT_TRACE_FILE)[0] + '.txt'
|
|
||||||
self.target_text_file = target.path.join(self.target.working_directory, text_file_name)
|
|
||||||
self.target_binary = None
|
|
||||||
self.host_binary = None
|
|
||||||
self.start_time = None
|
|
||||||
self.stop_time = None
|
|
||||||
self.event_string = None
|
|
||||||
self.function_string = None
|
|
||||||
self._reset_needed = True
|
|
||||||
|
|
||||||
# Setup tracing paths
|
|
||||||
self.available_events_file = self.target.path.join(self.tracing_path, 'available_events')
|
|
||||||
self.available_functions_file = self.target.path.join(self.tracing_path, 'available_filter_functions')
|
|
||||||
self.buffer_size_file = self.target.path.join(self.tracing_path, 'buffer_size_kb')
|
|
||||||
self.current_tracer_file = self.target.path.join(self.tracing_path, 'current_tracer')
|
|
||||||
self.function_profile_file = self.target.path.join(self.tracing_path, 'function_profile_enabled')
|
|
||||||
self.marker_file = self.target.path.join(self.tracing_path, 'trace_marker')
|
|
||||||
self.ftrace_filter_file = self.target.path.join(self.tracing_path, 'set_ftrace_filter')
|
|
||||||
|
|
||||||
self.host_binary = which('trace-cmd')
|
|
||||||
self.kernelshark = which('kernelshark')
|
|
||||||
|
|
||||||
if not self.target.is_rooted:
|
|
||||||
raise TargetError('trace-cmd instrument cannot be used on an unrooted device.')
|
|
||||||
if self.autoreport and not self.report_on_target and self.host_binary is None:
|
|
||||||
raise HostError('trace-cmd binary must be installed on the host if autoreport=True.')
|
|
||||||
if self.autoview and self.kernelshark is None:
|
|
||||||
raise HostError('kernelshark binary must be installed on the host if autoview=True.')
|
|
||||||
if not no_install:
|
|
||||||
host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi, 'trace-cmd')
|
|
||||||
self.target_binary = self.target.install(host_file)
|
|
||||||
else:
|
|
||||||
if not self.target.is_installed('trace-cmd'):
|
|
||||||
raise TargetError('No trace-cmd found on device and no_install=True is specified.')
|
|
||||||
self.target_binary = 'trace-cmd'
|
|
||||||
|
|
||||||
# Validate required events to be traced
|
|
||||||
available_events = self.target.execute(
|
|
||||||
'cat {}'.format(self.available_events_file),
|
|
||||||
as_root=True).splitlines()
|
|
||||||
selected_events = []
|
|
||||||
for event in self.events:
|
|
||||||
# Convert globs supported by FTrace into valid regexp globs
|
|
||||||
_event = event
|
|
||||||
if event[0] != '*':
|
|
||||||
_event = '*' + event
|
|
||||||
event_re = re.compile(_event.replace('*', '.*'))
|
|
||||||
# Select events matching the required ones
|
|
||||||
if len(list(filter(event_re.match, available_events))) == 0:
|
|
||||||
message = 'Event [{}] not available for tracing'.format(event)
|
|
||||||
if strict:
|
|
||||||
raise TargetError(message)
|
|
||||||
self.target.logger.warning(message)
|
|
||||||
else:
|
|
||||||
selected_events.append(event)
|
|
||||||
# If function profiling is enabled we always need at least one event.
|
|
||||||
# Thus, if not other events have been specified, try to add at least
|
|
||||||
# a tracepoint which is always available and possibly triggered few
|
|
||||||
# times.
|
|
||||||
if self.functions and len(selected_events) == 0:
|
|
||||||
selected_events = ['sched_wakeup_new']
|
|
||||||
self.event_string = _build_trace_events(selected_events)
|
|
||||||
|
|
||||||
# Check for function tracing support
|
|
||||||
if self.functions:
|
|
||||||
if not self.target.file_exists(self.function_profile_file):
|
|
||||||
raise TargetError('Function profiling not supported. '\
|
|
||||||
'A kernel build with CONFIG_FUNCTION_PROFILER enable is required')
|
|
||||||
# Validate required functions to be traced
|
|
||||||
available_functions = self.target.execute(
|
|
||||||
'cat {}'.format(self.available_functions_file),
|
|
||||||
as_root=True).splitlines()
|
|
||||||
selected_functions = []
|
|
||||||
for function in self.functions:
|
|
||||||
if function not in available_functions:
|
|
||||||
message = 'Function [{}] not available for profiling'.format(function)
|
|
||||||
if strict:
|
|
||||||
raise TargetError(message)
|
|
||||||
self.target.logger.warning(message)
|
|
||||||
else:
|
|
||||||
selected_functions.append(function)
|
|
||||||
self.function_string = _build_trace_functions(selected_functions)
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
if self.buffer_size:
|
|
||||||
self._set_buffer_size()
|
|
||||||
self.target.execute('{} reset'.format(self.target_binary),
|
|
||||||
as_root=True, timeout=TIMEOUT)
|
|
||||||
self._reset_needed = False
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.start_time = time.time()
|
|
||||||
if self._reset_needed:
|
|
||||||
self.reset()
|
|
||||||
self.target.execute('{} start {}'.format(self.target_binary, self.event_string),
|
|
||||||
as_root=True)
|
|
||||||
if self.automark:
|
|
||||||
self.mark_start()
|
|
||||||
if 'cpufreq' in self.target.modules:
|
|
||||||
self.logger.debug('Trace CPUFreq frequencies')
|
|
||||||
self.target.cpufreq.trace_frequencies()
|
|
||||||
if 'cpuidle' in self.target.modules:
|
|
||||||
self.logger.debug('Trace CPUIdle states')
|
|
||||||
self.target.cpuidle.perturb_cpus()
|
|
||||||
# Enable kernel function profiling
|
|
||||||
if self.functions:
|
|
||||||
self.target.execute('echo nop > {}'.format(self.current_tracer_file),
|
|
||||||
as_root=True)
|
|
||||||
self.target.execute('echo 0 > {}'.format(self.function_profile_file),
|
|
||||||
as_root=True)
|
|
||||||
self.target.execute('echo {} > {}'.format(self.function_string, self.ftrace_filter_file),
|
|
||||||
as_root=True)
|
|
||||||
self.target.execute('echo 1 > {}'.format(self.function_profile_file),
|
|
||||||
as_root=True)
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
# Disable kernel function profiling
|
|
||||||
if self.functions:
|
|
||||||
self.target.execute('echo 1 > {}'.format(self.function_profile_file),
|
|
||||||
as_root=True)
|
|
||||||
if 'cpufreq' in self.target.modules:
|
|
||||||
self.logger.debug('Trace CPUFreq frequencies')
|
|
||||||
self.target.cpufreq.trace_frequencies()
|
|
||||||
self.stop_time = time.time()
|
|
||||||
if self.automark:
|
|
||||||
self.mark_stop()
|
|
||||||
self.target.execute('{} stop'.format(self.target_binary),
|
|
||||||
timeout=TIMEOUT, as_root=True)
|
|
||||||
self._reset_needed = True
|
|
||||||
|
|
||||||
def get_trace(self, outfile):
|
|
||||||
if os.path.isdir(outfile):
|
|
||||||
outfile = os.path.join(outfile, os.path.basename(self.target_output_file))
|
|
||||||
self.target.execute('{0} extract -o {1}; chmod 666 {1}'.format(self.target_binary,
|
|
||||||
self.target_output_file),
|
|
||||||
timeout=TIMEOUT, as_root=True)
|
|
||||||
|
|
||||||
# The size of trace.dat will depend on how long trace-cmd was running.
|
|
||||||
# Therefore timout for the pull command must also be adjusted
|
|
||||||
# accordingly.
|
|
||||||
pull_timeout = 10 * (self.stop_time - self.start_time)
|
|
||||||
self.target.pull(self.target_output_file, outfile, timeout=pull_timeout)
|
|
||||||
if not os.path.isfile(outfile):
|
|
||||||
self.logger.warning('Binary trace not pulled from device.')
|
|
||||||
else:
|
|
||||||
if self.autoreport:
|
|
||||||
textfile = os.path.splitext(outfile)[0] + '.txt'
|
|
||||||
if self.report_on_target:
|
|
||||||
self.generate_report_on_target()
|
|
||||||
self.target.pull(self.target_text_file,
|
|
||||||
textfile, timeout=pull_timeout)
|
|
||||||
else:
|
|
||||||
self.report(outfile, textfile)
|
|
||||||
if self.autoview:
|
|
||||||
self.view(outfile)
|
|
||||||
|
|
||||||
def get_stats(self, outfile):
|
|
||||||
if not self.functions:
|
|
||||||
return
|
|
||||||
|
|
||||||
if os.path.isdir(outfile):
|
|
||||||
outfile = os.path.join(outfile, OUTPUT_PROFILE_FILE)
|
|
||||||
output = self.target._execute_util('ftrace_get_function_stats',
|
|
||||||
as_root=True)
|
|
||||||
|
|
||||||
function_stats = {}
|
|
||||||
for line in output.splitlines():
|
|
||||||
# Match a new CPU dataset
|
|
||||||
match = CPU_RE.search(line)
|
|
||||||
if match:
|
|
||||||
cpu_id = int(match.group(1))
|
|
||||||
function_stats[cpu_id] = {}
|
|
||||||
self.logger.debug("Processing stats for CPU%d...", cpu_id)
|
|
||||||
continue
|
|
||||||
# Match a new function dataset
|
|
||||||
match = STATS_RE.search(line)
|
|
||||||
if match:
|
|
||||||
fname = match.group(1)
|
|
||||||
function_stats[cpu_id][fname] = {
|
|
||||||
'hits' : int(match.group(2)),
|
|
||||||
'time' : float(match.group(3)),
|
|
||||||
'avg' : float(match.group(4)),
|
|
||||||
's_2' : float(match.group(5)),
|
|
||||||
}
|
|
||||||
self.logger.debug(" %s: %s",
|
|
||||||
fname, function_stats[cpu_id][fname])
|
|
||||||
|
|
||||||
self.logger.debug("FTrace stats output [%s]...", outfile)
|
|
||||||
with open(outfile, 'w') as fh:
|
|
||||||
json.dump(function_stats, fh, indent=4)
|
|
||||||
self.logger.debug("FTrace function stats save in [%s]", outfile)
|
|
||||||
|
|
||||||
return function_stats
|
|
||||||
|
|
||||||
def report(self, binfile, destfile):
|
|
||||||
# To get the output of trace.dat, trace-cmd must be installed
|
|
||||||
# This is done host-side because the generated file is very large
|
|
||||||
try:
|
|
||||||
command = '{} report {} > {}'.format(self.host_binary, binfile, destfile)
|
|
||||||
self.logger.debug(command)
|
|
||||||
process = subprocess.Popen(command, stderr=subprocess.PIPE, shell=True)
|
|
||||||
_, error = process.communicate()
|
|
||||||
if sys.version_info[0] == 3:
|
|
||||||
error = error.decode(sys.stdout.encoding, 'replace')
|
|
||||||
if process.returncode:
|
|
||||||
raise TargetError('trace-cmd returned non-zero exit code {}'.format(process.returncode))
|
|
||||||
if error:
|
|
||||||
# logged at debug level, as trace-cmd always outputs some
|
|
||||||
# errors that seem benign.
|
|
||||||
self.logger.debug(error)
|
|
||||||
if os.path.isfile(destfile):
|
|
||||||
self.logger.debug('Verifying traces.')
|
|
||||||
with open(destfile) as fh:
|
|
||||||
for line in fh:
|
|
||||||
if 'EVENTS DROPPED' in line:
|
|
||||||
self.logger.warning('Dropped events detected.')
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.logger.debug('Trace verified.')
|
|
||||||
else:
|
|
||||||
self.logger.warning('Could not generate trace.txt.')
|
|
||||||
except OSError:
|
|
||||||
raise HostError('Could not find trace-cmd. Please make sure it is installed and is in PATH.')
|
|
||||||
|
|
||||||
def generate_report_on_target(self):
|
|
||||||
command = '{} report {} > {}'.format(self.target_binary,
|
|
||||||
self.target_output_file,
|
|
||||||
self.target_text_file)
|
|
||||||
self.target.execute(command, timeout=TIMEOUT)
|
|
||||||
|
|
||||||
def view(self, binfile):
|
|
||||||
check_output('{} {}'.format(self.kernelshark, binfile), shell=True)
|
|
||||||
|
|
||||||
def teardown(self):
|
|
||||||
self.target.remove(self.target.path.join(self.target.working_directory, OUTPUT_TRACE_FILE))
|
|
||||||
|
|
||||||
def mark_start(self):
|
|
||||||
self.target.write_value(self.marker_file, TRACE_MARKER_START, verify=False)
|
|
||||||
|
|
||||||
def mark_stop(self):
|
|
||||||
self.target.write_value(self.marker_file, TRACE_MARKER_STOP, verify=False)
|
|
||||||
|
|
||||||
def _set_buffer_size(self):
|
|
||||||
target_buffer_size = self.buffer_size
|
|
||||||
attempt_buffer_size = target_buffer_size
|
|
||||||
buffer_size = 0
|
|
||||||
floor = 1000 if target_buffer_size > 1000 else target_buffer_size
|
|
||||||
while attempt_buffer_size >= floor:
|
|
||||||
self.target.write_value(self.buffer_size_file, attempt_buffer_size, verify=False)
|
|
||||||
buffer_size = self.target.read_int(self.buffer_size_file)
|
|
||||||
if buffer_size == attempt_buffer_size:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
attempt_buffer_size -= self.buffer_size_step
|
|
||||||
if buffer_size == target_buffer_size:
|
|
||||||
return
|
|
||||||
while attempt_buffer_size < target_buffer_size:
|
|
||||||
attempt_buffer_size += self.buffer_size_step
|
|
||||||
self.target.write_value(self.buffer_size_file, attempt_buffer_size, verify=False)
|
|
||||||
buffer_size = self.target.read_int(self.buffer_size_file)
|
|
||||||
if attempt_buffer_size != buffer_size:
|
|
||||||
message = 'Failed to set trace buffer size to {}, value set was {}'
|
|
||||||
self.logger.warning(message.format(target_buffer_size, buffer_size))
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
def _build_trace_events(events):
|
|
||||||
event_string = ' '.join(['-e {}'.format(e) for e in events])
|
|
||||||
return event_string
|
|
||||||
|
|
||||||
def _build_trace_functions(functions):
|
|
||||||
function_string = " ".join(functions)
|
|
||||||
return function_string
|
|
@ -12,5 +12,3 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
990
devlib/utils/asyn.py
Normal file
990
devlib/utils/asyn.py
Normal file
@ -0,0 +1,990 @@
|
|||||||
|
# Copyright 2013-2018 ARM Limited
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Async-related utilities
|
||||||
|
"""
|
||||||
|
|
||||||
|
import abc
|
||||||
|
import asyncio
|
||||||
|
import contextvars
|
||||||
|
import functools
|
||||||
|
import itertools
|
||||||
|
import contextlib
|
||||||
|
import pathlib
|
||||||
|
import queue
|
||||||
|
import os.path
|
||||||
|
import inspect
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
from weakref import WeakSet, WeakKeyDictionary
|
||||||
|
|
||||||
|
from greenlet import greenlet
|
||||||
|
|
||||||
|
|
||||||
|
def create_task(awaitable, name=None):
|
||||||
|
if isinstance(awaitable, asyncio.Task):
|
||||||
|
task = awaitable
|
||||||
|
else:
|
||||||
|
task = asyncio.create_task(awaitable)
|
||||||
|
if name is None:
|
||||||
|
name = getattr(awaitable, '__qualname__', None)
|
||||||
|
task.name = name
|
||||||
|
return task
|
||||||
|
|
||||||
|
|
||||||
|
def _close_loop(loop):
|
||||||
|
if loop is not None:
|
||||||
|
try:
|
||||||
|
loop.run_until_complete(loop.shutdown_asyncgens())
|
||||||
|
try:
|
||||||
|
shutdown_default_executor = loop.shutdown_default_executor
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
loop.run_until_complete(shutdown_default_executor())
|
||||||
|
finally:
|
||||||
|
loop.close()
|
||||||
|
|
||||||
|
|
||||||
|
class AsyncManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.task_tree = dict()
|
||||||
|
self.resources = dict()
|
||||||
|
|
||||||
|
def track_access(self, access):
|
||||||
|
"""
|
||||||
|
Register the given ``access`` to have been handled by the current
|
||||||
|
async task.
|
||||||
|
|
||||||
|
:param access: Access that were done.
|
||||||
|
:type access: ConcurrentAccessBase
|
||||||
|
|
||||||
|
This allows :func:`concurrently` to check that concurrent tasks did not
|
||||||
|
step on each other's toes.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
task = asyncio.current_task()
|
||||||
|
except RuntimeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.resources.setdefault(task, set()).add(access)
|
||||||
|
|
||||||
|
async def concurrently(self, awaitables):
|
||||||
|
"""
|
||||||
|
Await concurrently for the given awaitables, and cancel them as soon as
|
||||||
|
one raises an exception.
|
||||||
|
"""
|
||||||
|
awaitables = list(awaitables)
|
||||||
|
|
||||||
|
# Avoid creating asyncio.Tasks when it's not necessary, as it will
|
||||||
|
# disable a the blocking path optimization of Target._execute_async()
|
||||||
|
# that uses blocking calls as long as there is only one asyncio.Task
|
||||||
|
# running on the event loop.
|
||||||
|
if len(awaitables) == 1:
|
||||||
|
return [await awaitables[0]]
|
||||||
|
|
||||||
|
tasks = list(map(create_task, awaitables))
|
||||||
|
|
||||||
|
current_task = asyncio.current_task()
|
||||||
|
task_tree = self.task_tree
|
||||||
|
|
||||||
|
try:
|
||||||
|
node = task_tree[current_task]
|
||||||
|
except KeyError:
|
||||||
|
is_root_task = True
|
||||||
|
node = set()
|
||||||
|
else:
|
||||||
|
is_root_task = False
|
||||||
|
task_tree[current_task] = node
|
||||||
|
|
||||||
|
task_tree.update({
|
||||||
|
child: set()
|
||||||
|
for child in tasks
|
||||||
|
})
|
||||||
|
node.update(tasks)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await asyncio.gather(*tasks)
|
||||||
|
except BaseException:
|
||||||
|
for task in tasks:
|
||||||
|
task.cancel()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
|
||||||
|
def get_children(task):
|
||||||
|
immediate_children = task_tree[task]
|
||||||
|
return frozenset(
|
||||||
|
itertools.chain(
|
||||||
|
[task],
|
||||||
|
immediate_children,
|
||||||
|
itertools.chain.from_iterable(
|
||||||
|
map(get_children, immediate_children)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get the resources created during the execution of each subtask
|
||||||
|
# (directly or indirectly)
|
||||||
|
resources = {
|
||||||
|
task: frozenset(
|
||||||
|
itertools.chain.from_iterable(
|
||||||
|
self.resources.get(child, [])
|
||||||
|
for child in get_children(task)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for task in tasks
|
||||||
|
}
|
||||||
|
for (task1, resources1), (task2, resources2) in itertools.combinations(resources.items(), 2):
|
||||||
|
for res1, res2 in itertools.product(resources1, resources2):
|
||||||
|
if issubclass(res2.__class__, res1.__class__) and res1.overlap_with(res2):
|
||||||
|
raise RuntimeError(
|
||||||
|
'Overlapping resources manipulated in concurrent async tasks: {} (task {}) and {} (task {})'.format(res1, task1.name, res2, task2.name)
|
||||||
|
)
|
||||||
|
|
||||||
|
if is_root_task:
|
||||||
|
self.resources.clear()
|
||||||
|
task_tree.clear()
|
||||||
|
|
||||||
|
async def map_concurrently(self, f, keys):
|
||||||
|
"""
|
||||||
|
Similar to :meth:`concurrently`,
|
||||||
|
but maps the given function ``f`` on the given ``keys``.
|
||||||
|
|
||||||
|
:return: A dictionary with ``keys`` as keys, and function result as
|
||||||
|
values.
|
||||||
|
"""
|
||||||
|
keys = list(keys)
|
||||||
|
return dict(zip(
|
||||||
|
keys,
|
||||||
|
await self.concurrently(map(f, keys))
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def compose(*coros):
|
||||||
|
"""
|
||||||
|
Compose coroutines, feeding the output of each as the input of the next
|
||||||
|
one.
|
||||||
|
|
||||||
|
``await compose(f, g)(x)`` is equivalent to ``await f(await g(x))``
|
||||||
|
|
||||||
|
.. note:: In Haskell, ``compose f g h`` would be equivalent to ``f <=< g <=< h``
|
||||||
|
"""
|
||||||
|
async def f(*args, **kwargs):
|
||||||
|
empty_dict = {}
|
||||||
|
for coro in reversed(coros):
|
||||||
|
x = coro(*args, **kwargs)
|
||||||
|
# Allow mixing corountines and regular functions
|
||||||
|
if asyncio.isfuture(x):
|
||||||
|
x = await x
|
||||||
|
args = [x]
|
||||||
|
kwargs = empty_dict
|
||||||
|
|
||||||
|
return x
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
class _AsyncPolymorphicFunction:
|
||||||
|
"""
|
||||||
|
A callable that allows exposing both a synchronous and asynchronous API.
|
||||||
|
|
||||||
|
When called, the blocking synchronous operation is called. The ```asyn``
|
||||||
|
attribute gives access to the asynchronous version of the function, and all
|
||||||
|
the other attribute access will be redirected to the async function.
|
||||||
|
"""
|
||||||
|
def __init__(self, asyn, blocking):
|
||||||
|
self.asyn = asyn
|
||||||
|
self.blocking = blocking
|
||||||
|
functools.update_wrapper(self, asyn)
|
||||||
|
|
||||||
|
def __get__(self, *args, **kwargs):
|
||||||
|
return self.__class__(
|
||||||
|
asyn=self.asyn.__get__(*args, **kwargs),
|
||||||
|
blocking=self.blocking.__get__(*args, **kwargs),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ensure inspect.iscoroutinefunction() does not detect us as being async,
|
||||||
|
# since __call__ is not.
|
||||||
|
@property
|
||||||
|
def __code__(self):
|
||||||
|
return self.__call__.__code__
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.blocking(*args, **kwargs)
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.asyn, attr)
|
||||||
|
|
||||||
|
|
||||||
|
class memoized_method:
|
||||||
|
"""
|
||||||
|
Decorator to memmoize a method.
|
||||||
|
|
||||||
|
It works for:
|
||||||
|
|
||||||
|
* async methods (coroutine functions)
|
||||||
|
* non-async methods
|
||||||
|
* method already decorated with :func:`devlib.asyn.asyncf`.
|
||||||
|
|
||||||
|
.. note:: This decorator does not rely on hacks to hash unhashable data. If
|
||||||
|
such input is required, it will either have to be coerced to a hashable
|
||||||
|
first (e.g. converting a list to a tuple), or the code of
|
||||||
|
:func:`devlib.asyn.memoized_method` will have to be updated to do so.
|
||||||
|
"""
|
||||||
|
def __init__(self, f):
|
||||||
|
memo = self
|
||||||
|
|
||||||
|
sig = inspect.signature(f)
|
||||||
|
|
||||||
|
def bind(self, *args, **kwargs):
|
||||||
|
bound = sig.bind(self, *args, **kwargs)
|
||||||
|
bound.apply_defaults()
|
||||||
|
key = (bound.args[1:], tuple(sorted(bound.kwargs.items())))
|
||||||
|
|
||||||
|
return (key, bound.args, bound.kwargs)
|
||||||
|
|
||||||
|
def get_cache(self):
|
||||||
|
try:
|
||||||
|
cache = self.__dict__[memo.name]
|
||||||
|
except KeyError:
|
||||||
|
cache = {}
|
||||||
|
self.__dict__[memo.name] = cache
|
||||||
|
return cache
|
||||||
|
|
||||||
|
|
||||||
|
if inspect.iscoroutinefunction(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
async def wrapper(self, *args, **kwargs):
|
||||||
|
cache = get_cache(self)
|
||||||
|
key, args, kwargs = bind(self, *args, **kwargs)
|
||||||
|
try:
|
||||||
|
return cache[key]
|
||||||
|
except KeyError:
|
||||||
|
x = await f(*args, **kwargs)
|
||||||
|
cache[key] = x
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(self, *args, **kwargs):
|
||||||
|
cache = get_cache(self)
|
||||||
|
key, args, kwargs = bind(self, *args, **kwargs)
|
||||||
|
try:
|
||||||
|
return cache[key]
|
||||||
|
except KeyError:
|
||||||
|
x = f(*args, **kwargs)
|
||||||
|
cache[key] = x
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
self.f = wrapper
|
||||||
|
self._name = f.__name__
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return '__memoization_cache_of_' + self._name
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.f(*args, **kwargs)
|
||||||
|
|
||||||
|
def __get__(self, obj, owner=None):
|
||||||
|
return self.f.__get__(obj, owner)
|
||||||
|
|
||||||
|
def __set__(self, obj, value):
|
||||||
|
raise RuntimeError("Cannot monkey-patch a memoized function")
|
||||||
|
|
||||||
|
def __set_name__(self, owner, name):
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
|
||||||
|
class _Genlet(greenlet):
|
||||||
|
"""
|
||||||
|
Generator-like object based on ``greenlets``. It allows nested :class:`_Genlet`
|
||||||
|
to make their parent yield on their behalf, as if callees could decide to
|
||||||
|
be annotated ``yield from`` without modifying the caller.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# Forward the context variables to the greenlet, which will not happen
|
||||||
|
# by default:
|
||||||
|
# https://greenlet.readthedocs.io/en/latest/contextvars.html
|
||||||
|
self.gr_context = contextvars.copy_context()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_coro(cls, coro):
|
||||||
|
"""
|
||||||
|
Create a :class:`_Genlet` from a given coroutine, treating it as a
|
||||||
|
generator.
|
||||||
|
"""
|
||||||
|
f = lambda value: self.consume_coro(coro, value)
|
||||||
|
self = cls(f)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def consume_coro(self, coro, value):
|
||||||
|
"""
|
||||||
|
Send ``value`` to ``coro`` then consume the coroutine, passing all its
|
||||||
|
yielded actions to the enclosing :class:`_Genlet`. This allows crossing
|
||||||
|
blocking calls layers as if they were async calls with `await`.
|
||||||
|
"""
|
||||||
|
excep = None
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
if excep is None:
|
||||||
|
future = coro.send(value)
|
||||||
|
else:
|
||||||
|
future = coro.throw(excep)
|
||||||
|
|
||||||
|
except StopIteration as e:
|
||||||
|
return e.value
|
||||||
|
else:
|
||||||
|
parent = self.parent
|
||||||
|
# Switch back to the consumer that returns the values via
|
||||||
|
# send()
|
||||||
|
try:
|
||||||
|
value = parent.switch(future)
|
||||||
|
except BaseException as e:
|
||||||
|
excep = e
|
||||||
|
value = None
|
||||||
|
else:
|
||||||
|
excep = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_enclosing(cls):
|
||||||
|
"""
|
||||||
|
Get the immediately enclosing :class:`_Genlet` in the callstack or
|
||||||
|
``None``.
|
||||||
|
"""
|
||||||
|
g = greenlet.getcurrent()
|
||||||
|
while not (isinstance(g, cls) or g is None):
|
||||||
|
g = g.parent
|
||||||
|
return g
|
||||||
|
|
||||||
|
def _send_throw(self, value, excep):
|
||||||
|
self.parent = greenlet.getcurrent()
|
||||||
|
|
||||||
|
# Switch back to the function yielding values
|
||||||
|
if excep is None:
|
||||||
|
result = self.switch(value)
|
||||||
|
else:
|
||||||
|
result = self.throw(excep)
|
||||||
|
|
||||||
|
if self:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
raise StopIteration(result)
|
||||||
|
|
||||||
|
def gen_send(self, x):
|
||||||
|
"""
|
||||||
|
Similar to generators' ``send`` method.
|
||||||
|
"""
|
||||||
|
return self._send_throw(x, None)
|
||||||
|
|
||||||
|
def gen_throw(self, x):
|
||||||
|
"""
|
||||||
|
Similar to generators' ``throw`` method.
|
||||||
|
"""
|
||||||
|
return self._send_throw(None, x)
|
||||||
|
|
||||||
|
|
||||||
|
class _AwaitableGenlet:
|
||||||
|
"""
|
||||||
|
Wrap a coroutine with a :class:`_Genlet` and wrap that to be awaitable.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def wrap_coro(cls, coro):
|
||||||
|
async def coro_f():
|
||||||
|
# Make sure every new task will be instrumented since a task cannot
|
||||||
|
# yield futures on behalf of another task. If that were to happen,
|
||||||
|
# the task B trying to do a nested yield would switch back to task
|
||||||
|
# A, asking to yield on its behalf. Since the event loop would be
|
||||||
|
# currently handling task B, nothing would handle task A trying to
|
||||||
|
# yield on behalf of B, leading to a deadlock.
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
_install_task_factory(loop)
|
||||||
|
|
||||||
|
# Create a top-level _AwaitableGenlet that all nested runs will use
|
||||||
|
# to yield their futures
|
||||||
|
_coro = cls(coro)
|
||||||
|
|
||||||
|
return await _coro
|
||||||
|
|
||||||
|
return coro_f()
|
||||||
|
|
||||||
|
def __init__(self, coro):
|
||||||
|
self._coro = coro
|
||||||
|
|
||||||
|
def __await__(self):
|
||||||
|
coro = self._coro
|
||||||
|
is_started = inspect.iscoroutine(coro) and coro.cr_running
|
||||||
|
|
||||||
|
def genf():
|
||||||
|
gen = _Genlet.from_coro(coro)
|
||||||
|
value = None
|
||||||
|
excep = None
|
||||||
|
|
||||||
|
# The coroutine is already started, so we need to dispatch the
|
||||||
|
# value from the upcoming send() to the gen without running
|
||||||
|
# gen first.
|
||||||
|
if is_started:
|
||||||
|
try:
|
||||||
|
value = yield
|
||||||
|
except BaseException as e:
|
||||||
|
excep = e
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
if excep is None:
|
||||||
|
future = gen.gen_send(value)
|
||||||
|
else:
|
||||||
|
future = gen.gen_throw(excep)
|
||||||
|
except StopIteration as e:
|
||||||
|
return e.value
|
||||||
|
finally:
|
||||||
|
_set_current_context(gen.gr_context)
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = yield future
|
||||||
|
except BaseException as e:
|
||||||
|
excep = e
|
||||||
|
value = None
|
||||||
|
else:
|
||||||
|
excep = None
|
||||||
|
|
||||||
|
gen = genf()
|
||||||
|
if is_started:
|
||||||
|
# Start the generator so it waits at the first yield point
|
||||||
|
gen.gen_send(None)
|
||||||
|
|
||||||
|
return gen
|
||||||
|
|
||||||
|
|
||||||
|
def _allow_nested_run(coro):
|
||||||
|
if _Genlet.get_enclosing() is None:
|
||||||
|
return _AwaitableGenlet.wrap_coro(coro)
|
||||||
|
else:
|
||||||
|
return coro
|
||||||
|
|
||||||
|
|
||||||
|
def allow_nested_run(coro):
|
||||||
|
"""
|
||||||
|
Wrap the coroutine ``coro`` such that nested calls to :func:`run` will be
|
||||||
|
allowed.
|
||||||
|
|
||||||
|
.. warning:: The coroutine needs to be consumed in the same OS thread it
|
||||||
|
was created in.
|
||||||
|
"""
|
||||||
|
return _allow_nested_run(coro)
|
||||||
|
|
||||||
|
|
||||||
|
# This thread runs coroutines that cannot be ran on the event loop in the
|
||||||
|
# current thread. Instead, they are scheduled in a separate thread where
|
||||||
|
# another event loop has been setup, so we can wrap coroutines before
|
||||||
|
# dispatching them there.
|
||||||
|
_CORO_THREAD_EXECUTOR = ThreadPoolExecutor(
|
||||||
|
# Allow for a ridiculously large number so that we will never end up
|
||||||
|
# queuing one job after another. This is critical as we could otherwise end
|
||||||
|
# up in deadlock, if a job triggers another job and waits for it.
|
||||||
|
max_workers=2**64,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _check_executor_alive(executor):
|
||||||
|
try:
|
||||||
|
executor.submit(lambda: None)
|
||||||
|
except RuntimeError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
_PATCHED_LOOP_LOCK = threading.Lock()
|
||||||
|
_PATCHED_LOOP = WeakSet()
|
||||||
|
def _install_task_factory(loop):
|
||||||
|
"""
|
||||||
|
Install a task factory on the given event ``loop`` so that top-level
|
||||||
|
coroutines are wrapped using :func:`allow_nested_run`. This ensures that
|
||||||
|
the nested :func:`run` infrastructure will be available.
|
||||||
|
"""
|
||||||
|
def install(loop):
|
||||||
|
if sys.version_info >= (3, 11):
|
||||||
|
def default_factory(loop, coro, context=None):
|
||||||
|
return asyncio.Task(coro, loop=loop, context=context)
|
||||||
|
else:
|
||||||
|
def default_factory(loop, coro, context=None):
|
||||||
|
return asyncio.Task(coro, loop=loop)
|
||||||
|
|
||||||
|
make_task = loop.get_task_factory() or default_factory
|
||||||
|
def factory(loop, coro, context=None):
|
||||||
|
# Make sure each Task will be able to yield on behalf of its nested
|
||||||
|
# await beneath blocking layers
|
||||||
|
coro = _AwaitableGenlet.wrap_coro(coro)
|
||||||
|
return make_task(loop, coro, context=context)
|
||||||
|
|
||||||
|
loop.set_task_factory(factory)
|
||||||
|
|
||||||
|
with _PATCHED_LOOP_LOCK:
|
||||||
|
if loop in _PATCHED_LOOP:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
install(loop)
|
||||||
|
_PATCHED_LOOP.add(loop)
|
||||||
|
|
||||||
|
|
||||||
|
def _set_current_context(ctx):
|
||||||
|
"""
|
||||||
|
Get all the variable from the passed ``ctx`` and set them in the current
|
||||||
|
context.
|
||||||
|
"""
|
||||||
|
for var, val in ctx.items():
|
||||||
|
var.set(val)
|
||||||
|
|
||||||
|
|
||||||
|
class _CoroRunner(abc.ABC):
|
||||||
|
"""
|
||||||
|
ABC for an object that can execute multiple coroutines in a given
|
||||||
|
environment.
|
||||||
|
|
||||||
|
This allows running coroutines for which it might be an assumption, such as
|
||||||
|
the awaitables yielded by an async generator that are all attached to a
|
||||||
|
single event loop.
|
||||||
|
"""
|
||||||
|
@abc.abstractmethod
|
||||||
|
def _run(self, coro):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self, coro):
|
||||||
|
# Ensure we have a fresh coroutine. inspect.getcoroutinestate() does not
|
||||||
|
# work on all objects that asyncio creates on some version of Python, such
|
||||||
|
# as iterable_coroutine
|
||||||
|
assert not (inspect.iscoroutine(coro) and coro.cr_running)
|
||||||
|
return self._run(coro)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, tb):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class _ThreadCoroRunner(_CoroRunner):
|
||||||
|
"""
|
||||||
|
Run the coroutines on a thread picked from a
|
||||||
|
:class:`concurrent.futures.ThreadPoolExecutor`.
|
||||||
|
|
||||||
|
Critically, this allows running multiple coroutines out of the same thread,
|
||||||
|
which will be reserved until the runner ``__exit__`` method is called.
|
||||||
|
"""
|
||||||
|
def __init__(self, future, jobq, resq):
|
||||||
|
self._future = future
|
||||||
|
self._jobq = jobq
|
||||||
|
self._resq = resq
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _thread_f(jobq, resq):
|
||||||
|
def handle_jobs(runner):
|
||||||
|
while True:
|
||||||
|
job = jobq.get()
|
||||||
|
if job is None:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
ctx, coro = job
|
||||||
|
try:
|
||||||
|
value = ctx.run(runner.run, coro)
|
||||||
|
except BaseException as e:
|
||||||
|
value = None
|
||||||
|
excep = e
|
||||||
|
else:
|
||||||
|
excep = None
|
||||||
|
|
||||||
|
resq.put((ctx, excep, value))
|
||||||
|
|
||||||
|
with _LoopCoroRunner(None) as runner:
|
||||||
|
handle_jobs(runner)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_executor(cls, executor):
|
||||||
|
jobq = queue.SimpleQueue()
|
||||||
|
resq = queue.SimpleQueue()
|
||||||
|
|
||||||
|
try:
|
||||||
|
future = executor.submit(cls._thread_f, jobq, resq)
|
||||||
|
except RuntimeError as e:
|
||||||
|
if _check_executor_alive(executor):
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Devlib relies on nested asyncio implementation requiring threads. These threads are not available while shutting down the interpreter.')
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
jobq=jobq,
|
||||||
|
resq=resq,
|
||||||
|
future=future,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _run(self, coro):
|
||||||
|
ctx = contextvars.copy_context()
|
||||||
|
self._jobq.put((ctx, coro))
|
||||||
|
ctx, excep, value = self._resq.get()
|
||||||
|
|
||||||
|
_set_current_context(ctx)
|
||||||
|
|
||||||
|
if excep is None:
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
raise excep
|
||||||
|
|
||||||
|
def __exit__(self, *args, **kwargs):
|
||||||
|
self._jobq.put(None)
|
||||||
|
self._future.result()
|
||||||
|
|
||||||
|
|
||||||
|
class _LoopCoroRunner(_CoroRunner):
|
||||||
|
"""
|
||||||
|
Run a coroutine on the given event loop.
|
||||||
|
|
||||||
|
The passed event loop is assumed to not be running. If ``None`` is passed,
|
||||||
|
a new event loop will be created in ``__enter__`` and closed in
|
||||||
|
``__exit__``.
|
||||||
|
"""
|
||||||
|
def __init__(self, loop):
|
||||||
|
self.loop = loop
|
||||||
|
self._owned = False
|
||||||
|
|
||||||
|
def _run(self, coro):
|
||||||
|
loop = self.loop
|
||||||
|
|
||||||
|
# Back-propagate the contextvars that could have been modified by the
|
||||||
|
# coroutine. This could be handled by asyncio.Runner().run(...,
|
||||||
|
# context=...) or loop.create_task(..., context=...) but these APIs are
|
||||||
|
# only available since Python 3.11
|
||||||
|
ctx = None
|
||||||
|
async def capture_ctx():
|
||||||
|
nonlocal ctx
|
||||||
|
try:
|
||||||
|
return await _allow_nested_run(coro)
|
||||||
|
finally:
|
||||||
|
ctx = contextvars.copy_context()
|
||||||
|
|
||||||
|
try:
|
||||||
|
return loop.run_until_complete(capture_ctx())
|
||||||
|
finally:
|
||||||
|
_set_current_context(ctx)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
loop = self.loop
|
||||||
|
if loop is None:
|
||||||
|
owned = True
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
else:
|
||||||
|
owned = False
|
||||||
|
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
|
||||||
|
self.loop = loop
|
||||||
|
self._owned = owned
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args, **kwargs):
|
||||||
|
if self._owned:
|
||||||
|
asyncio.set_event_loop(None)
|
||||||
|
_close_loop(self.loop)
|
||||||
|
|
||||||
|
|
||||||
|
class _GenletCoroRunner(_CoroRunner):
|
||||||
|
"""
|
||||||
|
Run a coroutine assuming one of the parent coroutines was wrapped with
|
||||||
|
:func:`allow_nested_run`.
|
||||||
|
"""
|
||||||
|
def __init__(self, g):
|
||||||
|
self._g = g
|
||||||
|
|
||||||
|
def _run(self, coro):
|
||||||
|
return self._g.consume_coro(coro, None)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_runner():
|
||||||
|
executor = _CORO_THREAD_EXECUTOR
|
||||||
|
g = _Genlet.get_enclosing()
|
||||||
|
try:
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
except RuntimeError:
|
||||||
|
loop = None
|
||||||
|
|
||||||
|
# We have an coroutine wrapped with allow_nested_run() higher in the
|
||||||
|
# callstack, that we will be able to use as a conduit to yield the
|
||||||
|
# futures.
|
||||||
|
if g is not None:
|
||||||
|
return _GenletCoroRunner(g)
|
||||||
|
# No event loop setup, so we can just make our own
|
||||||
|
elif loop is None:
|
||||||
|
return _LoopCoroRunner(None)
|
||||||
|
# There is an event loop setup, but it is not currently running so we
|
||||||
|
# can just re-use it.
|
||||||
|
#
|
||||||
|
# TODO: for now, this path is dead since asyncio.get_running_loop() will
|
||||||
|
# always raise a RuntimeError if the loop is not running, even if
|
||||||
|
# asyncio.set_event_loop() was used.
|
||||||
|
elif not loop.is_running():
|
||||||
|
return _LoopCoroRunner(loop)
|
||||||
|
# There is an event loop currently running in our thread, so we cannot
|
||||||
|
# just create another event loop and install it since asyncio forbids
|
||||||
|
# that. The only choice is doing this in a separate thread that we
|
||||||
|
# fully control.
|
||||||
|
else:
|
||||||
|
return _ThreadCoroRunner.from_executor(executor)
|
||||||
|
|
||||||
|
|
||||||
|
def run(coro):
|
||||||
|
"""
|
||||||
|
Similar to :func:`asyncio.run` but can be called while an event loop is
|
||||||
|
running if a coroutine higher in the callstack has been wrapped using
|
||||||
|
:func:`allow_nested_run`.
|
||||||
|
|
||||||
|
Note that context variables from :mod:`contextvars` will be available in
|
||||||
|
the coroutine, and unlike with :func:`asyncio.run`, any update to them will
|
||||||
|
be reflected in the context of the caller. This allows context variable
|
||||||
|
updates to cross an arbitrary number of run layers, as if all those layers
|
||||||
|
were just part of the same coroutine.
|
||||||
|
"""
|
||||||
|
runner = _get_runner()
|
||||||
|
with runner as runner:
|
||||||
|
return runner.run(coro)
|
||||||
|
|
||||||
|
|
||||||
|
def asyncf(f):
|
||||||
|
"""
|
||||||
|
Decorator used to turn a coroutine into a blocking function, with an
|
||||||
|
optional asynchronous API.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
@asyncf
|
||||||
|
async def foo(x):
|
||||||
|
await do_some_async_things(x)
|
||||||
|
return x
|
||||||
|
|
||||||
|
# Blocking call, just as if the function was synchronous, except it may
|
||||||
|
# use asynchronous code inside, e.g. to do concurrent operations.
|
||||||
|
foo(42)
|
||||||
|
|
||||||
|
# Asynchronous API, foo.asyn being a corountine
|
||||||
|
await foo.asyn(42)
|
||||||
|
|
||||||
|
This allows the same implementation to be both used as blocking for ease of
|
||||||
|
use and backward compatibility, or exposed as a corountine for callers that
|
||||||
|
can deal with awaitables.
|
||||||
|
"""
|
||||||
|
@functools.wraps(f)
|
||||||
|
def blocking(*args, **kwargs):
|
||||||
|
# Since run() needs a corountine, make sure we provide one
|
||||||
|
async def wrapper():
|
||||||
|
x = f(*args, **kwargs)
|
||||||
|
# Async generators have to be consumed and accumulated in a list
|
||||||
|
# before crossing a blocking boundary.
|
||||||
|
if inspect.isasyncgen(x):
|
||||||
|
|
||||||
|
def genf():
|
||||||
|
asyncgen = x.__aiter__()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
yield run(asyncgen.__anext__())
|
||||||
|
except StopAsyncIteration:
|
||||||
|
return
|
||||||
|
|
||||||
|
return genf()
|
||||||
|
else:
|
||||||
|
return await x
|
||||||
|
return run(wrapper())
|
||||||
|
|
||||||
|
return _AsyncPolymorphicFunction(
|
||||||
|
asyn=f,
|
||||||
|
blocking=blocking,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class _AsyncPolymorphicCMState:
|
||||||
|
def __init__(self):
|
||||||
|
self.nesting = 0
|
||||||
|
self.runner = None
|
||||||
|
|
||||||
|
def _update_nesting(self, n):
|
||||||
|
x = self.nesting
|
||||||
|
assert x >= 0
|
||||||
|
x = x + n
|
||||||
|
self.nesting = x
|
||||||
|
return bool(x)
|
||||||
|
|
||||||
|
def _get_runner(self):
|
||||||
|
runner = self.runner
|
||||||
|
if runner is None:
|
||||||
|
assert not self.nesting
|
||||||
|
runner = _get_runner()
|
||||||
|
runner.__enter__()
|
||||||
|
self.runner = runner
|
||||||
|
return runner
|
||||||
|
|
||||||
|
def _cleanup_runner(self, force=False):
|
||||||
|
def cleanup():
|
||||||
|
self.runner = None
|
||||||
|
if runner is not None:
|
||||||
|
runner.__exit__(None, None, None)
|
||||||
|
|
||||||
|
runner = self.runner
|
||||||
|
if force:
|
||||||
|
cleanup()
|
||||||
|
else:
|
||||||
|
assert runner is not None
|
||||||
|
if not self._update_nesting(0):
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
class _AsyncPolymorphicCM:
|
||||||
|
"""
|
||||||
|
Wrap an async context manager such that it exposes a synchronous API as
|
||||||
|
well for backward compatibility.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, async_cm):
|
||||||
|
self.cm = async_cm
|
||||||
|
self._state = threading.local()
|
||||||
|
|
||||||
|
def _get_state(self):
|
||||||
|
try:
|
||||||
|
return self._state.x
|
||||||
|
except AttributeError:
|
||||||
|
state = _AsyncPolymorphicCMState()
|
||||||
|
self._state.x = state
|
||||||
|
return state
|
||||||
|
|
||||||
|
def _delete_state(self):
|
||||||
|
try:
|
||||||
|
del self._state.x
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __aenter__(self, *args, **kwargs):
|
||||||
|
return self.cm.__aenter__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __aexit__(self, *args, **kwargs):
|
||||||
|
return self.cm.__aexit__(*args, **kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _exit(state):
|
||||||
|
state._update_nesting(-1)
|
||||||
|
state._cleanup_runner()
|
||||||
|
|
||||||
|
def __enter__(self, *args, **kwargs):
|
||||||
|
state = self._get_state()
|
||||||
|
runner = state._get_runner()
|
||||||
|
|
||||||
|
# Increase the nesting count _before_ we start running the
|
||||||
|
# coroutine, in case it is a recursive context manager
|
||||||
|
state._update_nesting(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
coro = self.cm.__aenter__(*args, **kwargs)
|
||||||
|
return runner.run(coro)
|
||||||
|
except BaseException:
|
||||||
|
self._exit(state)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def __exit__(self, *args, **kwargs):
|
||||||
|
coro = self.cm.__aexit__(*args, **kwargs)
|
||||||
|
|
||||||
|
state = self._get_state()
|
||||||
|
runner = state._get_runner()
|
||||||
|
|
||||||
|
try:
|
||||||
|
return runner.run(coro)
|
||||||
|
finally:
|
||||||
|
self._exit(state)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self._get_state()._cleanup_runner(force=True)
|
||||||
|
|
||||||
|
|
||||||
|
def asynccontextmanager(f):
|
||||||
|
"""
|
||||||
|
Same as :func:`contextlib.asynccontextmanager` except that it can also be
|
||||||
|
used with a regular ``with`` statement for backward compatibility.
|
||||||
|
"""
|
||||||
|
f = contextlib.asynccontextmanager(f)
|
||||||
|
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
cm = f(*args, **kwargs)
|
||||||
|
return _AsyncPolymorphicCM(cm)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
class ConcurrentAccessBase(abc.ABC):
|
||||||
|
"""
|
||||||
|
Abstract Base Class for resources tracked by :func:`concurrently`.
|
||||||
|
"""
|
||||||
|
@abc.abstractmethod
|
||||||
|
def overlap_with(self, other):
|
||||||
|
"""
|
||||||
|
Return ``True`` if the resource overlaps with the given one.
|
||||||
|
|
||||||
|
:param other: Resources that should not overlap with ``self``.
|
||||||
|
:type other: devlib.utils.asym.ConcurrentAccessBase
|
||||||
|
|
||||||
|
.. note:: It is guaranteed that ``other`` will be a subclass of our
|
||||||
|
class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class PathAccess(ConcurrentAccessBase):
|
||||||
|
"""
|
||||||
|
Concurrent resource representing a file access.
|
||||||
|
|
||||||
|
:param namespace: Identifier of the namespace of the path. One of "target" or "host".
|
||||||
|
:type namespace: str
|
||||||
|
|
||||||
|
:param path: Normalized path to the file.
|
||||||
|
:type path: str
|
||||||
|
|
||||||
|
:param mode: Opening mode of the file. Can be ``"r"`` for read and ``"w"``
|
||||||
|
for writing.
|
||||||
|
:type mode: str
|
||||||
|
"""
|
||||||
|
def __init__(self, namespace, path, mode):
|
||||||
|
assert namespace in ('host', 'target')
|
||||||
|
self.namespace = namespace
|
||||||
|
assert mode in ('r', 'w')
|
||||||
|
self.mode = mode
|
||||||
|
self.path = os.path.abspath(path) if namespace == 'host' else os.path.normpath(path)
|
||||||
|
|
||||||
|
def overlap_with(self, other):
|
||||||
|
path1 = pathlib.Path(self.path).resolve()
|
||||||
|
path2 = pathlib.Path(other.path).resolve()
|
||||||
|
return (
|
||||||
|
self.namespace == other.namespace and
|
||||||
|
'w' in (self.mode, other.mode) and
|
||||||
|
(
|
||||||
|
path1 == path2 or
|
||||||
|
path1 in path2.parents or
|
||||||
|
path2 in path1.parents
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
mode = {
|
||||||
|
'r': 'read',
|
||||||
|
'w': 'write',
|
||||||
|
}[self.mode]
|
||||||
|
return '{} ({})'.format(self.path, mode)
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018 ARM Limited
|
# Copyright 2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -54,16 +54,12 @@ responsibility of the calling code to ensure that the file is closed properly.
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
import csv
|
import csv
|
||||||
import sys
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def csvwriter(filepath, *args, **kwargs):
|
def csvwriter(filepath, *args, **kwargs):
|
||||||
if sys.version_info[0] == 3:
|
wfh = open(filepath, 'w', newline='')
|
||||||
wfh = open(filepath, 'w', newline='')
|
|
||||||
else:
|
|
||||||
wfh = open(filepath, 'wb')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield csv.writer(wfh, *args, **kwargs)
|
yield csv.writer(wfh, *args, **kwargs)
|
||||||
@ -73,10 +69,7 @@ def csvwriter(filepath, *args, **kwargs):
|
|||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def csvreader(filepath, *args, **kwargs):
|
def csvreader(filepath, *args, **kwargs):
|
||||||
if sys.version_info[0] == 3:
|
fh = open(filepath, 'r', newline='')
|
||||||
fh = open(filepath, 'r', newline='')
|
|
||||||
else:
|
|
||||||
fh = open(filepath, 'rb')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield csv.reader(fh, *args, **kwargs)
|
yield csv.reader(fh, *args, **kwargs)
|
||||||
@ -85,16 +78,10 @@ def csvreader(filepath, *args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def create_writer(filepath, *args, **kwargs):
|
def create_writer(filepath, *args, **kwargs):
|
||||||
if sys.version_info[0] == 3:
|
wfh = open(filepath, 'w', newline='')
|
||||||
wfh = open(filepath, 'w', newline='')
|
|
||||||
else:
|
|
||||||
wfh = open(filepath, 'wb')
|
|
||||||
return csv.writer(wfh, *args, **kwargs), wfh
|
return csv.writer(wfh, *args, **kwargs), wfh
|
||||||
|
|
||||||
|
|
||||||
def create_reader(filepath, *args, **kwargs):
|
def create_reader(filepath, *args, **kwargs):
|
||||||
if sys.version_info[0] == 3:
|
fh = open(filepath, 'r', newline='')
|
||||||
fh = open(filepath, 'r', newline='')
|
|
||||||
else:
|
|
||||||
fh = open(filepath, 'rb')
|
|
||||||
return csv.reader(fh, *args, **kwargs), fh
|
return csv.reader(fh, *args, **kwargs), fh
|
||||||
|
@ -18,7 +18,7 @@ import logging
|
|||||||
from devlib.utils.types import numeric
|
from devlib.utils.types import numeric
|
||||||
|
|
||||||
|
|
||||||
GEM5STATS_FIELD_REGEX = re.compile("^(?P<key>[^- ]\S*) +(?P<value>[^#]+).+$")
|
GEM5STATS_FIELD_REGEX = re.compile(r"^(?P<key>[^- ]\S*) +(?P<value>[^#]+).+$")
|
||||||
GEM5STATS_DUMP_HEAD = '---------- Begin Simulation Statistics ----------'
|
GEM5STATS_DUMP_HEAD = '---------- Begin Simulation Statistics ----------'
|
||||||
GEM5STATS_DUMP_TAIL = '---------- End Simulation Statistics ----------'
|
GEM5STATS_DUMP_TAIL = '---------- End Simulation Statistics ----------'
|
||||||
GEM5STATS_ROI_NUMBER = 8
|
GEM5STATS_ROI_NUMBER = 8
|
||||||
@ -28,7 +28,7 @@ logger = logging.getLogger('gem5')
|
|||||||
|
|
||||||
def iter_statistics_dump(stats_file):
|
def iter_statistics_dump(stats_file):
|
||||||
'''
|
'''
|
||||||
Yields statistics dumps as dicts. The parameter is assumed to be a stream
|
Yields statistics dumps as dicts. The parameter is assumed to be a stream
|
||||||
reading from the statistics log file.
|
reading from the statistics log file.
|
||||||
'''
|
'''
|
||||||
cur_dump = {}
|
cur_dump = {}
|
||||||
@ -40,14 +40,13 @@ def iter_statistics_dump(stats_file):
|
|||||||
yield cur_dump
|
yield cur_dump
|
||||||
cur_dump = {}
|
cur_dump = {}
|
||||||
else:
|
else:
|
||||||
res = GEM5STATS_FIELD_REGEX.match(line)
|
res = GEM5STATS_FIELD_REGEX.match(line)
|
||||||
if res:
|
if res:
|
||||||
k = res.group("key")
|
k = res.group("key")
|
||||||
vtext = res.group("value")
|
vtext = res.group("value")
|
||||||
try:
|
try:
|
||||||
v = list(map(numeric, vtext.split()))
|
v = list(map(numeric, vtext.split()))
|
||||||
cur_dump[k] = v[0] if len(v)==1 else set(v)
|
cur_dump[k] = v[0] if len(v) == 1 else set(v)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
msg = 'Found non-numeric entry in gem5 stats ({}: {})'
|
msg = 'Found non-numeric entry in gem5 stats ({}: {})'
|
||||||
logger.warning(msg.format(k, vtext))
|
logger.warning(msg.format(k, vtext))
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2013-2018 ARM Limited
|
# Copyright 2013-2024 ARM Limited
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -18,28 +18,38 @@
|
|||||||
Miscellaneous functions that don't fit anywhere else.
|
Miscellaneous functions that don't fit anywhere else.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import division
|
from contextlib import contextmanager
|
||||||
|
from functools import partial, reduce, wraps
|
||||||
|
from itertools import groupby
|
||||||
|
from operator import itemgetter
|
||||||
|
from weakref import WeakSet
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
import ctypes
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import pkgutil
|
||||||
|
import random
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
import threading
|
|
||||||
import signal
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import pkgutil
|
import sys
|
||||||
import logging
|
|
||||||
import random
|
|
||||||
import ctypes
|
|
||||||
import threading
|
import threading
|
||||||
from operator import itemgetter
|
import types
|
||||||
from itertools import groupby
|
import warnings
|
||||||
from functools import partial
|
|
||||||
|
|
||||||
import wrapt
|
import wrapt
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from contextlib import ExitStack
|
||||||
|
except AttributeError:
|
||||||
|
from contextlib2 import ExitStack
|
||||||
|
|
||||||
|
from shlex import quote
|
||||||
from past.builtins import basestring
|
from past.builtins import basestring
|
||||||
|
|
||||||
|
# pylint: disable=redefined-builtin
|
||||||
from devlib.exception import HostError, TimeoutError
|
from devlib.exception import HostError, TimeoutError
|
||||||
from functools import reduce
|
|
||||||
|
|
||||||
|
|
||||||
# ABI --> architectures list
|
# ABI --> architectures list
|
||||||
@ -127,9 +137,6 @@ def get_cpu_name(implementer, part, variant):
|
|||||||
|
|
||||||
|
|
||||||
def preexec_function():
|
def preexec_function():
|
||||||
# Ignore the SIGINT signal by setting the handler to the standard
|
|
||||||
# signal handler SIG_IGN.
|
|
||||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
||||||
# Change process group in case we have to kill the subprocess and all of
|
# Change process group in case we have to kill the subprocess and all of
|
||||||
# its children later.
|
# its children later.
|
||||||
# TODO: this is Unix-specific; would be good to find an OS-agnostic way
|
# TODO: this is Unix-specific; would be good to find an OS-agnostic way
|
||||||
@ -138,15 +145,21 @@ def preexec_function():
|
|||||||
|
|
||||||
|
|
||||||
check_output_logger = logging.getLogger('check_output')
|
check_output_logger = logging.getLogger('check_output')
|
||||||
# Popen is not thread safe. If two threads attempt to call it at the same time,
|
|
||||||
# one may lock up. See https://bugs.python.org/issue12739.
|
def get_subprocess(command, **kwargs):
|
||||||
check_output_lock = threading.Lock()
|
if 'stdout' in kwargs:
|
||||||
|
raise ValueError('stdout argument not allowed, it will be overridden.')
|
||||||
|
return subprocess.Popen(command,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
preexec_fn=preexec_function,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def check_output(command, timeout=None, ignore=None, inputtext=None,
|
def check_subprocess_output(process, timeout=None, ignore=None, inputtext=None):
|
||||||
combined_output=False, **kwargs):
|
output = None
|
||||||
"""This is a version of subprocess.check_output that adds a timeout parameter to kill
|
error = None
|
||||||
the subprocess if it does not return within the specified time."""
|
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
if ignore is None:
|
if ignore is None:
|
||||||
ignore = []
|
ignore = []
|
||||||
@ -155,49 +168,36 @@ def check_output(command, timeout=None, ignore=None, inputtext=None,
|
|||||||
elif not isinstance(ignore, list) and ignore != 'all':
|
elif not isinstance(ignore, list) and ignore != 'all':
|
||||||
message = 'Invalid value for ignore parameter: "{}"; must be an int or a list'
|
message = 'Invalid value for ignore parameter: "{}"; must be an int or a list'
|
||||||
raise ValueError(message.format(ignore))
|
raise ValueError(message.format(ignore))
|
||||||
if 'stdout' in kwargs:
|
|
||||||
raise ValueError('stdout argument not allowed, it will be overridden.')
|
|
||||||
|
|
||||||
def callback(pid):
|
with process:
|
||||||
try:
|
try:
|
||||||
check_output_logger.debug('{} timed out; sending SIGKILL'.format(pid))
|
output, error = process.communicate(inputtext, timeout=timeout)
|
||||||
os.killpg(pid, signal.SIGKILL)
|
except subprocess.TimeoutExpired as e:
|
||||||
except OSError:
|
timeout_expired = e
|
||||||
pass # process may have already terminated.
|
else:
|
||||||
|
timeout_expired = None
|
||||||
|
|
||||||
with check_output_lock:
|
# Currently errors=replace is needed as 0x8c throws an error
|
||||||
stderr = subprocess.STDOUT if combined_output else subprocess.PIPE
|
output = output.decode(sys.stdout.encoding or 'utf-8', "replace") if output else ''
|
||||||
process = subprocess.Popen(command,
|
error = error.decode(sys.stderr.encoding or 'utf-8', "replace") if error else ''
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=stderr,
|
|
||||||
stdin=subprocess.PIPE,
|
|
||||||
preexec_fn=preexec_function,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
if timeout:
|
if timeout_expired:
|
||||||
timer = threading.Timer(timeout, callback, [process.pid, ])
|
raise TimeoutError(process.args, output='\n'.join([output, error]))
|
||||||
timer.start()
|
|
||||||
|
|
||||||
try:
|
retcode = process.returncode
|
||||||
output, error = process.communicate(inputtext)
|
if retcode and ignore != 'all' and retcode not in ignore:
|
||||||
if sys.version_info[0] == 3:
|
raise subprocess.CalledProcessError(retcode, process.args, output, error)
|
||||||
# Currently errors=replace is needed as 0x8c throws an error
|
|
||||||
output = output.decode(sys.stdout.encoding, "replace")
|
|
||||||
if error:
|
|
||||||
error = error.decode(sys.stderr.encoding, "replace")
|
|
||||||
finally:
|
|
||||||
if timeout:
|
|
||||||
timer.cancel()
|
|
||||||
|
|
||||||
retcode = process.poll()
|
|
||||||
if retcode:
|
|
||||||
if retcode == -9: # killed, assume due to timeout callback
|
|
||||||
raise TimeoutError(command, output='\n'.join([output or '', error or '']))
|
|
||||||
elif ignore != 'all' and retcode not in ignore:
|
|
||||||
raise subprocess.CalledProcessError(retcode, command, output='\n'.join([output or '', error or '']))
|
|
||||||
return output, error
|
return output, error
|
||||||
|
|
||||||
|
|
||||||
|
def check_output(command, timeout=None, ignore=None, inputtext=None, **kwargs):
|
||||||
|
"""This is a version of subprocess.check_output that adds a timeout parameter to kill
|
||||||
|
the subprocess if it does not return within the specified time."""
|
||||||
|
process = get_subprocess(command, **kwargs)
|
||||||
|
return check_subprocess_output(process, timeout=timeout, ignore=ignore, inputtext=inputtext)
|
||||||
|
|
||||||
|
|
||||||
def walk_modules(path):
|
def walk_modules(path):
|
||||||
"""
|
"""
|
||||||
Given package name, return a list of all modules (including submodules, etc)
|
Given package name, return a list of all modules (including submodules, etc)
|
||||||
@ -235,6 +235,32 @@ def walk_modules(path):
|
|||||||
mods.append(submod)
|
mods.append(submod)
|
||||||
return mods
|
return mods
|
||||||
|
|
||||||
|
def redirect_streams(stdout, stderr, command):
|
||||||
|
"""
|
||||||
|
Update a command to redirect a given stream to /dev/null if it's
|
||||||
|
``subprocess.DEVNULL``.
|
||||||
|
|
||||||
|
:return: A tuple (stdout, stderr, command) with stream set to ``subprocess.PIPE``
|
||||||
|
if the `stream` parameter was set to ``subprocess.DEVNULL``.
|
||||||
|
"""
|
||||||
|
def redirect(stream, redirection):
|
||||||
|
if stream == subprocess.DEVNULL:
|
||||||
|
suffix = '{}/dev/null'.format(redirection)
|
||||||
|
elif stream == subprocess.STDOUT:
|
||||||
|
suffix = '{}&1'.format(redirection)
|
||||||
|
# Indicate that there is nothing to monitor for stderr anymore
|
||||||
|
# since it's merged into stdout
|
||||||
|
stream = subprocess.DEVNULL
|
||||||
|
else:
|
||||||
|
suffix = ''
|
||||||
|
|
||||||
|
return (stream, suffix)
|
||||||
|
|
||||||
|
stdout, suffix1 = redirect(stdout, '>')
|
||||||
|
stderr, suffix2 = redirect(stderr, '2>')
|
||||||
|
|
||||||
|
command = 'sh -c {} {} {}'.format(quote(command), suffix1, suffix2)
|
||||||
|
return (stdout, stderr, command)
|
||||||
|
|
||||||
def ensure_directory_exists(dirpath):
|
def ensure_directory_exists(dirpath):
|
||||||
"""A filter for directory paths to ensure they exist."""
|
"""A filter for directory paths to ensure they exist."""
|
||||||
@ -415,25 +441,51 @@ def convert_new_lines(text):
|
|||||||
""" Convert new lines to a common format. """
|
""" Convert new lines to a common format. """
|
||||||
return text.replace('\r\n', '\n').replace('\r', '\n')
|
return text.replace('\r\n', '\n').replace('\r', '\n')
|
||||||
|
|
||||||
|
def sanitize_cmd_template(cmd):
|
||||||
|
msg = (
|
||||||
|
'''Quoted placeholder should not be used, as it will result in quoting the text twice. {} should be used instead of '{}' or "{}" in the template: '''
|
||||||
|
)
|
||||||
|
for unwanted in ('"{}"', "'{}'"):
|
||||||
|
if unwanted in cmd:
|
||||||
|
warnings.warn(msg + cmd, stacklevel=2)
|
||||||
|
cmd = cmd.replace(unwanted, '{}')
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
|
||||||
def escape_quotes(text):
|
def escape_quotes(text):
|
||||||
"""Escape quotes, and escaped quotes, in the specified text."""
|
"""
|
||||||
|
Escape quotes, and escaped quotes, in the specified text.
|
||||||
|
|
||||||
|
.. note:: :func:`shlex.quote` should be favored where possible.
|
||||||
|
"""
|
||||||
return re.sub(r'\\("|\')', r'\\\\\1', text).replace('\'', '\\\'').replace('\"', '\\\"')
|
return re.sub(r'\\("|\')', r'\\\\\1', text).replace('\'', '\\\'').replace('\"', '\\\"')
|
||||||
|
|
||||||
|
|
||||||
def escape_single_quotes(text):
|
def escape_single_quotes(text):
|
||||||
"""Escape single quotes, and escaped single quotes, in the specified text."""
|
"""
|
||||||
|
Escape single quotes, and escaped single quotes, in the specified text.
|
||||||
|
|
||||||
|
.. note:: :func:`shlex.quote` should be favored where possible.
|
||||||
|
"""
|
||||||
return re.sub(r'\\("|\')', r'\\\\\1', text).replace('\'', '\'\\\'\'')
|
return re.sub(r'\\("|\')', r'\\\\\1', text).replace('\'', '\'\\\'\'')
|
||||||
|
|
||||||
|
|
||||||
def escape_double_quotes(text):
|
def escape_double_quotes(text):
|
||||||
"""Escape double quotes, and escaped double quotes, in the specified text."""
|
"""
|
||||||
|
Escape double quotes, and escaped double quotes, in the specified text.
|
||||||
|
|
||||||
|
.. note:: :func:`shlex.quote` should be favored where possible.
|
||||||
|
"""
|
||||||
return re.sub(r'\\("|\')', r'\\\\\1', text).replace('\"', '\\\"')
|
return re.sub(r'\\("|\')', r'\\\\\1', text).replace('\"', '\\\"')
|
||||||
|
|
||||||
|
|
||||||
def escape_spaces(text):
|
def escape_spaces(text):
|
||||||
"""Escape spaces in the specified text"""
|
"""
|
||||||
return text.replace(' ', '\ ')
|
Escape spaces in the specified text
|
||||||
|
|
||||||
|
.. note:: :func:`shlex.quote` should be favored where possible.
|
||||||
|
"""
|
||||||
|
return text.replace(' ', '\\ ')
|
||||||
|
|
||||||
|
|
||||||
def getch(count=1):
|
def getch(count=1):
|
||||||
@ -523,6 +575,12 @@ def get_random_string(length):
|
|||||||
|
|
||||||
class LoadSyntaxError(Exception):
|
class LoadSyntaxError(Exception):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message(self):
|
||||||
|
if self.args:
|
||||||
|
return self.args[0]
|
||||||
|
return str(self)
|
||||||
|
|
||||||
def __init__(self, message, filepath, lineno):
|
def __init__(self, message, filepath, lineno):
|
||||||
super(LoadSyntaxError, self).__init__(message)
|
super(LoadSyntaxError, self).__init__(message)
|
||||||
self.filepath = filepath
|
self.filepath = filepath
|
||||||
@ -533,12 +591,33 @@ class LoadSyntaxError(Exception):
|
|||||||
return message.format(self.filepath, self.lineno, self.message)
|
return message.format(self.filepath, self.lineno, self.message)
|
||||||
|
|
||||||
|
|
||||||
|
def load_struct_from_yaml(filepath):
|
||||||
|
"""
|
||||||
|
Parses a config structure from a YAML file.
|
||||||
|
The structure should be composed of basic Python types.
|
||||||
|
|
||||||
|
:param filepath: Input file which contains YAML data.
|
||||||
|
:type filepath: str
|
||||||
|
|
||||||
|
:raises LoadSyntaxError: if there is a syntax error in YAML data.
|
||||||
|
|
||||||
|
:return: A dictionary which contains parsed YAML data
|
||||||
|
:rtype: Dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
yaml = YAML(typ='safe', pure=True)
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as file_handler:
|
||||||
|
return yaml.load(file_handler)
|
||||||
|
except yaml.YAMLError as ex:
|
||||||
|
message = ex.message if hasattr(ex, 'message') else ''
|
||||||
|
lineno = ex.problem_mark.line if hasattr(ex, 'problem_mark') else None
|
||||||
|
raise LoadSyntaxError(message, filepath=filepath, lineno=lineno) from ex
|
||||||
|
|
||||||
|
|
||||||
RAND_MOD_NAME_LEN = 30
|
RAND_MOD_NAME_LEN = 30
|
||||||
BAD_CHARS = string.punctuation + string.whitespace
|
BAD_CHARS = string.punctuation + string.whitespace
|
||||||
if sys.version_info[0] == 3:
|
TRANS_TABLE = str.maketrans(BAD_CHARS, '_' * len(BAD_CHARS))
|
||||||
TRANS_TABLE = str.maketrans(BAD_CHARS, '_' * len(BAD_CHARS))
|
|
||||||
else:
|
|
||||||
TRANS_TABLE = string.maketrans(BAD_CHARS, '_' * len(BAD_CHARS))
|
|
||||||
|
|
||||||
|
|
||||||
def to_identifier(text):
|
def to_identifier(text):
|
||||||
@ -576,6 +655,7 @@ def ranges_to_list(ranges_string):
|
|||||||
|
|
||||||
def list_to_ranges(values):
|
def list_to_ranges(values):
|
||||||
"""Converts a list, e.g ``[0,2,3,4]``, into a sysfs-style ranges string, e.g. ``"0,2-4"``"""
|
"""Converts a list, e.g ``[0,2,3,4]``, into a sysfs-style ranges string, e.g. ``"0,2-4"``"""
|
||||||
|
values = sorted(values)
|
||||||
range_groups = []
|
range_groups = []
|
||||||
for _, g in groupby(enumerate(values), lambda i_x: i_x[0] - i_x[1]):
|
for _, g in groupby(enumerate(values), lambda i_x: i_x[0] - i_x[1]):
|
||||||
range_groups.append(list(map(itemgetter(1), g)))
|
range_groups.append(list(map(itemgetter(1), g)))
|
||||||
@ -639,13 +719,21 @@ def __get_memo_id(obj):
|
|||||||
|
|
||||||
|
|
||||||
@wrapt.decorator
|
@wrapt.decorator
|
||||||
def memoized(wrapped, instance, args, kwargs):
|
def memoized(wrapped, instance, args, kwargs): # pylint: disable=unused-argument
|
||||||
"""A decorator for memoizing functions and methods."""
|
"""
|
||||||
|
A decorator for memoizing functions and methods.
|
||||||
|
|
||||||
|
.. warning:: this may not detect changes to mutable types. As long as the
|
||||||
|
memoized function was used with an object as an argument
|
||||||
|
before, the cached result will be returned, even if the
|
||||||
|
structure of the object (e.g. a list) has changed in the mean time.
|
||||||
|
|
||||||
|
"""
|
||||||
func_id = repr(wrapped)
|
func_id = repr(wrapped)
|
||||||
|
|
||||||
def memoize_wrapper(*args, **kwargs):
|
def memoize_wrapper(*args, **kwargs):
|
||||||
id_string = func_id + ','.join([__get_memo_id(a) for a in args])
|
id_string = func_id + ','.join([__get_memo_id(a) for a in args])
|
||||||
id_string += ','.join('{}={}'.format(k, v)
|
id_string += ','.join('{}={}'.format(k, __get_memo_id(v))
|
||||||
for k, v in kwargs.items())
|
for k, v in kwargs.items())
|
||||||
if id_string not in __memo_cache:
|
if id_string not in __memo_cache:
|
||||||
__memo_cache[id_string] = wrapped(*args, **kwargs)
|
__memo_cache[id_string] = wrapped(*args, **kwargs)
|
||||||
@ -653,3 +741,296 @@ def memoized(wrapped, instance, args, kwargs):
|
|||||||
|
|
||||||
return memoize_wrapper(*args, **kwargs)
|
return memoize_wrapper(*args, **kwargs)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def batch_contextmanager(f, kwargs_list):
|
||||||
|
"""
|
||||||
|
Return a context manager that will call the ``f`` callable with the keyword
|
||||||
|
arguments dict in the given list, in one go.
|
||||||
|
|
||||||
|
:param f: Callable expected to return a context manager.
|
||||||
|
|
||||||
|
:param kwargs_list: list of kwargs dictionaries to be used to call ``f``.
|
||||||
|
:type kwargs_list: list(dict)
|
||||||
|
"""
|
||||||
|
with ExitStack() as stack:
|
||||||
|
for kwargs in kwargs_list:
|
||||||
|
stack.enter_context(f(**kwargs))
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
class nullcontext:
|
||||||
|
"""
|
||||||
|
Backport of Python 3.7 ``contextlib.nullcontext``
|
||||||
|
|
||||||
|
This context manager does nothing, so it can be used as a default
|
||||||
|
placeholder for code that needs to select at runtime what context manager
|
||||||
|
to use.
|
||||||
|
|
||||||
|
:param enter_result: Object that will be bound to the target of the with
|
||||||
|
statement, or `None` if nothing is specified.
|
||||||
|
:type enter_result: object
|
||||||
|
"""
|
||||||
|
def __init__(self, enter_result=None):
|
||||||
|
self.enter_result = enter_result
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self.enter_result
|
||||||
|
|
||||||
|
async def __aenter__(self):
|
||||||
|
return self.enter_result
|
||||||
|
|
||||||
|
def __exit__(*_):
|
||||||
|
return
|
||||||
|
|
||||||
|
async def __aexit__(*_):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class tls_property:
|
||||||
|
"""
|
||||||
|
Use it like `property` decorator, but the result will be memoized per
|
||||||
|
thread. When the owning thread dies, the values for that thread will be
|
||||||
|
destroyed.
|
||||||
|
|
||||||
|
In order to get the values, it's necessary to call the object
|
||||||
|
given by the property. This is necessary in order to be able to add methods
|
||||||
|
to that object, like :meth:`_BoundTLSProperty.get_all_values`.
|
||||||
|
|
||||||
|
Values can be set and deleted as well, which will be a thread-local set.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self.factory.__name__
|
||||||
|
|
||||||
|
def __init__(self, factory):
|
||||||
|
self.factory = factory
|
||||||
|
# Lock accesses to shared WeakKeyDictionary and WeakSet
|
||||||
|
self.lock = threading.RLock()
|
||||||
|
|
||||||
|
def __get__(self, instance, owner=None):
|
||||||
|
return _BoundTLSProperty(self, instance, owner)
|
||||||
|
|
||||||
|
def _get_value(self, instance, owner):
|
||||||
|
tls, values = self._get_tls(instance)
|
||||||
|
try:
|
||||||
|
return tls.value
|
||||||
|
except AttributeError:
|
||||||
|
# Bind the method to `instance`
|
||||||
|
f = self.factory.__get__(instance, owner)
|
||||||
|
obj = f()
|
||||||
|
tls.value = obj
|
||||||
|
# Since that's a WeakSet, values will be removed automatically once
|
||||||
|
# the threading.local variable that holds them is destroyed
|
||||||
|
with self.lock:
|
||||||
|
values.add(obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def _get_all_values(self, instance, owner):
|
||||||
|
with self.lock:
|
||||||
|
# Grab a reference to all the objects at the time of the call by
|
||||||
|
# using a regular set
|
||||||
|
tls, values = self._get_tls(instance=instance)
|
||||||
|
return set(values)
|
||||||
|
|
||||||
|
def __set__(self, instance, value):
|
||||||
|
tls, values = self._get_tls(instance)
|
||||||
|
tls.value = value
|
||||||
|
with self.lock:
|
||||||
|
values.add(value)
|
||||||
|
|
||||||
|
def __delete__(self, instance):
|
||||||
|
tls, values = self._get_tls(instance)
|
||||||
|
with self.lock:
|
||||||
|
try:
|
||||||
|
value = tls.value
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
values.discard(value)
|
||||||
|
del tls.value
|
||||||
|
|
||||||
|
def _get_tls(self, instance):
|
||||||
|
dct = instance.__dict__
|
||||||
|
name = self.name
|
||||||
|
try:
|
||||||
|
# Using instance.__dict__[self.name] is safe as
|
||||||
|
# getattr(instance, name) will return the property instead, as
|
||||||
|
# the property is a descriptor
|
||||||
|
tls = dct[name]
|
||||||
|
except KeyError:
|
||||||
|
with self.lock:
|
||||||
|
# Double check after taking the lock to avoid a race
|
||||||
|
if name not in dct:
|
||||||
|
tls = (threading.local(), WeakSet())
|
||||||
|
dct[name] = tls
|
||||||
|
|
||||||
|
return tls
|
||||||
|
|
||||||
|
@property
|
||||||
|
def basic_property(self):
|
||||||
|
"""
|
||||||
|
Return a basic property that can be used to access the TLS value
|
||||||
|
without having to call it first.
|
||||||
|
|
||||||
|
The drawback is that it's not possible to do anything over than
|
||||||
|
getting/setting/deleting.
|
||||||
|
"""
|
||||||
|
def getter(instance, owner=None):
|
||||||
|
prop = self.__get__(instance, owner)
|
||||||
|
return prop()
|
||||||
|
|
||||||
|
return property(getter, self.__set__, self.__delete__)
|
||||||
|
|
||||||
|
class _BoundTLSProperty:
|
||||||
|
"""
|
||||||
|
Simple proxy object to allow either calling it to get the TLS value, or get
|
||||||
|
some other informations by calling methods.
|
||||||
|
"""
|
||||||
|
def __init__(self, tls_property, instance, owner):
|
||||||
|
self.tls_property = tls_property
|
||||||
|
self.instance = instance
|
||||||
|
self.owner = owner
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
return self.tls_property._get_value(
|
||||||
|
instance=self.instance,
|
||||||
|
owner=self.owner,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_all_values(self):
|
||||||
|
"""
|
||||||
|
Returns all the thread-local values currently in use in the process for
|
||||||
|
that property for that instance.
|
||||||
|
"""
|
||||||
|
return self.tls_property._get_all_values(
|
||||||
|
instance=self.instance,
|
||||||
|
owner=self.owner,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InitCheckpointMeta(type):
|
||||||
|
"""
|
||||||
|
Metaclass providing an ``initialized`` and ``is_in_use`` boolean attributes
|
||||||
|
on instances.
|
||||||
|
|
||||||
|
``initialized`` is set to ``True`` once the ``__init__`` constructor has
|
||||||
|
returned. It will deal cleanly with nested calls to ``super().__init__``.
|
||||||
|
|
||||||
|
``is_in_use`` is set to ``True`` when an instance method is being called.
|
||||||
|
This allows to detect reentrance.
|
||||||
|
"""
|
||||||
|
def __new__(metacls, name, bases, dct, **kwargs):
|
||||||
|
cls = super().__new__(metacls, name, bases, dct, **kwargs)
|
||||||
|
init_f = cls.__init__
|
||||||
|
|
||||||
|
@wraps(init_f)
|
||||||
|
def init_wrapper(self, *args, **kwargs):
|
||||||
|
self.initialized = False
|
||||||
|
self.is_in_use = False
|
||||||
|
|
||||||
|
# Track the nesting of super()__init__ to set initialized=True only
|
||||||
|
# when the outer level is finished
|
||||||
|
try:
|
||||||
|
stack = self._init_stack
|
||||||
|
except AttributeError:
|
||||||
|
stack = []
|
||||||
|
self._init_stack = stack
|
||||||
|
|
||||||
|
stack.append(init_f)
|
||||||
|
try:
|
||||||
|
x = init_f(self, *args, **kwargs)
|
||||||
|
finally:
|
||||||
|
stack.pop()
|
||||||
|
|
||||||
|
if not stack:
|
||||||
|
self.initialized = True
|
||||||
|
del self._init_stack
|
||||||
|
|
||||||
|
return x
|
||||||
|
|
||||||
|
cls.__init__ = init_wrapper
|
||||||
|
|
||||||
|
# Set the is_in_use attribute to allow external code to detect if the
|
||||||
|
# methods are about to be re-entered.
|
||||||
|
def make_wrapper(f):
|
||||||
|
if f is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@wraps(f)
|
||||||
|
def wrapper(self, *args, **kwargs):
|
||||||
|
f_ = f.__get__(self, self.__class__)
|
||||||
|
initial_state = self.is_in_use
|
||||||
|
try:
|
||||||
|
self.is_in_use = True
|
||||||
|
return f_(*args, **kwargs)
|
||||||
|
finally:
|
||||||
|
self.is_in_use = initial_state
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
# This will not decorate methods defined in base classes, but we cannot
|
||||||
|
# use inspect.getmembers() as it uses __get__ to bind the attributes to
|
||||||
|
# the class, making staticmethod indistinguishible from instance
|
||||||
|
# methods.
|
||||||
|
for name, attr in cls.__dict__.items():
|
||||||
|
# Only wrap the methods (exposed as functions), not things like
|
||||||
|
# classmethod or staticmethod
|
||||||
|
if (
|
||||||
|
name not in ('__init__', '__new__') and
|
||||||
|
isinstance(attr, types.FunctionType)
|
||||||
|
):
|
||||||
|
setattr(cls, name, make_wrapper(attr))
|
||||||
|
elif isinstance(attr, property):
|
||||||
|
prop = property(
|
||||||
|
fget=make_wrapper(attr.fget),
|
||||||
|
fset=make_wrapper(attr.fset),
|
||||||
|
fdel=make_wrapper(attr.fdel),
|
||||||
|
doc=attr.__doc__,
|
||||||
|
)
|
||||||
|
setattr(cls, name, prop)
|
||||||
|
|
||||||
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
class InitCheckpoint(metaclass=InitCheckpointMeta):
|
||||||
|
"""
|
||||||
|
Inherit from this class to set the :class:`InitCheckpointMeta` metaclass.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def groupby_value(dct):
|
||||||
|
"""
|
||||||
|
Process the input dict such that all keys sharing the same values are
|
||||||
|
grouped in a tuple, used as key in the returned dict.
|
||||||
|
"""
|
||||||
|
key = itemgetter(1)
|
||||||
|
items = sorted(dct.items(), key=key)
|
||||||
|
return {
|
||||||
|
tuple(map(itemgetter(0), _items)): v
|
||||||
|
for v, _items in groupby(items, key=key)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def safe_extract(tar, path=".", members=None, *, numeric_owner=False):
|
||||||
|
"""
|
||||||
|
A wrapper around TarFile.extract all to mitigate CVE-2007-4995
|
||||||
|
(see https://www.trellix.com/en-us/about/newsroom/stories/research/tarfile-exploiting-the-world.html)
|
||||||
|
"""
|
||||||
|
|
||||||
|
for member in tar.getmembers():
|
||||||
|
member_path = os.path.join(path, member.name)
|
||||||
|
if not _is_within_directory(path, member_path):
|
||||||
|
raise Exception("Attempted Path Traversal in Tar File")
|
||||||
|
|
||||||
|
tar.extractall(path, members, numeric_owner=numeric_owner)
|
||||||
|
|
||||||
|
def _is_within_directory(directory, target):
|
||||||
|
|
||||||
|
abs_directory = os.path.abspath(directory)
|
||||||
|
abs_target = os.path.abspath(target)
|
||||||
|
|
||||||
|
prefix = os.path.commonprefix([abs_directory, abs_target])
|
||||||
|
|
||||||
|
return prefix == abs_directory
|
||||||
|
@ -28,18 +28,14 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import getopt
|
import getopt
|
||||||
import subprocess
|
|
||||||
import logging
|
import logging
|
||||||
import signal
|
import signal
|
||||||
import serial
|
import sys
|
||||||
import time
|
|
||||||
import math
|
|
||||||
|
|
||||||
logger = logging.getLogger('aep-parser')
|
logger = logging.getLogger('aep-parser')
|
||||||
|
|
||||||
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class AepParser(object):
|
class AepParser(object):
|
||||||
prepared = False
|
prepared = False
|
||||||
|
|
||||||
@ -94,7 +90,7 @@ class AepParser(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if parent not in virtual:
|
if parent not in virtual:
|
||||||
virtual[parent] = { supply : index }
|
virtual[parent] = {supply : index}
|
||||||
|
|
||||||
virtual[parent][supply] = index
|
virtual[parent][supply] = index
|
||||||
|
|
||||||
@ -102,7 +98,7 @@ class AepParser(object):
|
|||||||
# child
|
# child
|
||||||
for supply in list(virtual.keys()):
|
for supply in list(virtual.keys()):
|
||||||
if len(virtual[supply]) == 1:
|
if len(virtual[supply]) == 1:
|
||||||
del virtual[supply];
|
del virtual[supply]
|
||||||
|
|
||||||
for supply in list(virtual.keys()):
|
for supply in list(virtual.keys()):
|
||||||
# Add label, hide and duplicate columns for virtual domains
|
# Add label, hide and duplicate columns for virtual domains
|
||||||
@ -121,7 +117,7 @@ class AepParser(object):
|
|||||||
|
|
||||||
label[0] = array[0]
|
label[0] = array[0]
|
||||||
unit[0] = "(S)"
|
unit[0] = "(S)"
|
||||||
for i in range(1,len(array)):
|
for i in range(1, len(array)):
|
||||||
label[i] = array[i][:-3]
|
label[i] = array[i][:-3]
|
||||||
unit[i] = array[i][-3:]
|
unit[i] = array[i][-3:]
|
||||||
|
|
||||||
@ -138,7 +134,7 @@ class AepParser(object):
|
|||||||
# By default we assume that there is no child
|
# By default we assume that there is no child
|
||||||
duplicate = [0] * len(label)
|
duplicate = [0] * len(label)
|
||||||
|
|
||||||
for i in range(len(label)):
|
for i in range(len(label)): # pylint: disable=consider-using-enumerate
|
||||||
# We only care about time and Watt
|
# We only care about time and Watt
|
||||||
if label[i] == 'time':
|
if label[i] == 'time':
|
||||||
hide[i] = 0
|
hide[i] = 0
|
||||||
@ -167,7 +163,7 @@ class AepParser(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_text(array, hide):
|
def parse_text(array, hide):
|
||||||
data = [0]*len(array)
|
data = [0]*len(array)
|
||||||
for i in range(len(array)):
|
for i in range(len(array)): # pylint: disable=consider-using-enumerate
|
||||||
if hide[i]:
|
if hide[i]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -193,18 +189,18 @@ class AepParser(object):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delta_nrj(array, delta, min, max, hide):
|
def delta_nrj(array, delta, minimu, maximum, hide):
|
||||||
# Compute the energy consumed in this time slice and add it
|
# Compute the energy consumed in this time slice and add it
|
||||||
# delta[0] is used to save the last time stamp
|
# delta[0] is used to save the last time stamp
|
||||||
|
|
||||||
if (delta[0] < 0):
|
if delta[0] < 0:
|
||||||
delta[0] = array[0]
|
delta[0] = array[0]
|
||||||
|
|
||||||
time = array[0] - delta[0]
|
time = array[0] - delta[0]
|
||||||
if (time <= 0):
|
if time <= 0:
|
||||||
return delta
|
return delta
|
||||||
|
|
||||||
for i in range(len(array)):
|
for i in range(len(array)): # pylint: disable=consider-using-enumerate
|
||||||
if hide[i]:
|
if hide[i]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -213,10 +209,10 @@ class AepParser(object):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (data < min[i]):
|
if data < minimu[i]:
|
||||||
min[i] = data
|
minimu[i] = data
|
||||||
if (data > max[i]):
|
if data > maximum[i]:
|
||||||
max[i] = data
|
maximum[i] = data
|
||||||
delta[i] += time * data
|
delta[i] += time * data
|
||||||
|
|
||||||
# save last time stamp
|
# save last time stamp
|
||||||
@ -225,11 +221,11 @@ class AepParser(object):
|
|||||||
return delta
|
return delta
|
||||||
|
|
||||||
def output_label(self, label, hide):
|
def output_label(self, label, hide):
|
||||||
self.fo.write(label[0]+"(uS)")
|
self.fo.write(label[0] + "(uS)")
|
||||||
for i in range(1, len(label)):
|
for i in range(1, len(label)):
|
||||||
if hide[i]:
|
if hide[i]:
|
||||||
continue
|
continue
|
||||||
self.fo.write(" "+label[i]+"(uW)")
|
self.fo.write(" " + label[i] + "(uW)")
|
||||||
|
|
||||||
self.fo.write("\n")
|
self.fo.write("\n")
|
||||||
|
|
||||||
@ -248,34 +244,34 @@ class AepParser(object):
|
|||||||
|
|
||||||
self.fo.write("\n")
|
self.fo.write("\n")
|
||||||
|
|
||||||
def prepare(self, infile, outfile, summaryfile):
|
# pylint: disable-redefined-outer-name,
|
||||||
|
def prepare(self, input_file, outfile, summaryfile):
|
||||||
try:
|
try:
|
||||||
self.fi = open(infile, "r")
|
self.fi = open(input_file, "r")
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.warn('Unable to open input file {}'.format(infile))
|
logger.warning('Unable to open input file {}'.format(input_file))
|
||||||
logger.warn('Usage: parse_arp.py -i <inputfile> [-o <outputfile>]')
|
logger.warning('Usage: parse_arp.py -i <inputfile> [-o <outputfile>]')
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
self.parse = True
|
self.parse = True
|
||||||
if len(outfile) > 0:
|
if outfile:
|
||||||
try:
|
try:
|
||||||
self.fo = open(outfile, "w")
|
self.fo = open(outfile, "w")
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.warn('Unable to create {}'.format(outfile))
|
logger.warning('Unable to create {}'.format(outfile))
|
||||||
self.parse = False
|
self.parse = False
|
||||||
else:
|
else:
|
||||||
self.parse = False
|
self.parse = False
|
||||||
|
|
||||||
self.summary = True
|
self.summary = True
|
||||||
if len(summaryfile) > 0:
|
if summaryfile:
|
||||||
try:
|
try:
|
||||||
self.fs = open(summaryfile, "w")
|
self.fs = open(summaryfile, "w")
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.warn('Unable to create {}'.format(summaryfile))
|
logger.warning('Unable to create {}'.format(summaryfile))
|
||||||
self.fs = sys.stdout
|
self.fs = sys.stdout
|
||||||
else:
|
else:
|
||||||
self.fs = sys.stdout
|
self.fs = sys.stdout
|
||||||
|
|
||||||
self.prepared = True
|
self.prepared = True
|
||||||
|
|
||||||
@ -291,7 +287,8 @@ class AepParser(object):
|
|||||||
|
|
||||||
self.prepared = False
|
self.prepared = False
|
||||||
|
|
||||||
def parse_aep(self, start=0, lenght=-1):
|
# pylint: disable=too-many-branches,too-many-statements,redefined-outer-name,too-many-locals
|
||||||
|
def parse_aep(self, start=0, length=-1):
|
||||||
# Parse aep data and calculate the energy consumed
|
# Parse aep data and calculate the energy consumed
|
||||||
begin = 0
|
begin = 0
|
||||||
|
|
||||||
@ -302,7 +299,7 @@ class AepParser(object):
|
|||||||
lines = self.fi.readlines()
|
lines = self.fi.readlines()
|
||||||
|
|
||||||
for myline in lines:
|
for myline in lines:
|
||||||
array = myline.split()
|
array = myline.split()
|
||||||
|
|
||||||
if "#" in myline:
|
if "#" in myline:
|
||||||
# update power topology
|
# update power topology
|
||||||
@ -331,8 +328,8 @@ class AepParser(object):
|
|||||||
|
|
||||||
# Init arrays
|
# Init arrays
|
||||||
nrj = [0]*len(label)
|
nrj = [0]*len(label)
|
||||||
min = [100000000]*len(label)
|
minimum = [100000000]*len(label)
|
||||||
max = [0]*len(label)
|
maximum = [0]*len(label)
|
||||||
offset = [0]*len(label)
|
offset = [0]*len(label)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@ -342,21 +339,21 @@ class AepParser(object):
|
|||||||
|
|
||||||
# get 1st time stamp
|
# get 1st time stamp
|
||||||
if begin <= 0:
|
if begin <= 0:
|
||||||
being = data[0]
|
begin = data[0]
|
||||||
|
|
||||||
# skip data before start
|
# skip data before start
|
||||||
if (data[0]-begin) < start:
|
if (data[0]-begin) < start:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# stop after lenght
|
# stop after length
|
||||||
if lenght >= 0 and (data[0]-begin) > (start + lenght):
|
if length >= 0 and (data[0]-begin) > (start + length):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# add virtual domains
|
# add virtual domains
|
||||||
data = self.add_virtual_data(data, virtual)
|
data = self.add_virtual_data(data, virtual)
|
||||||
|
|
||||||
# extract power figures
|
# extract power figures
|
||||||
self.delta_nrj(data, nrj, min, max, hide)
|
self.delta_nrj(data, nrj, minimum, maximum, hide)
|
||||||
|
|
||||||
# write data into new file
|
# write data into new file
|
||||||
if self.parse:
|
if self.parse:
|
||||||
@ -365,7 +362,6 @@ class AepParser(object):
|
|||||||
# if there is no data just return
|
# if there is no data just return
|
||||||
if label_line or len(nrj) == 1:
|
if label_line or len(nrj) == 1:
|
||||||
raise ValueError('No data found in the data file. Please check the Arm Energy Probe')
|
raise ValueError('No data found in the data file. Please check the Arm Energy Probe')
|
||||||
return
|
|
||||||
|
|
||||||
# display energy consumption of each channel and total energy consumption
|
# display energy consumption of each channel and total energy consumption
|
||||||
total = 0
|
total = 0
|
||||||
@ -377,27 +373,33 @@ class AepParser(object):
|
|||||||
nrj[i] -= offset[i] * nrj[0]
|
nrj[i] -= offset[i] * nrj[0]
|
||||||
|
|
||||||
total_nrj = nrj[i]/1000000000000.0
|
total_nrj = nrj[i]/1000000000000.0
|
||||||
duration = (max[0]-min[0])/1000000.0
|
duration = (maximum[0]-minimum[0])/1000000.0
|
||||||
channel_name = label[i]
|
channel_name = label[i]
|
||||||
average_power = total_nrj/duration
|
average_power = total_nrj/duration
|
||||||
|
|
||||||
self.fs.write("Total nrj: %8.3f J for %s -- duration %8.3f sec -- min %8.3f W -- max %8.3f W\n" % (nrj[i]/1000000000000.0, label[i], (max[0]-min[0])/1000000.0, min[i]/1000000.0, max[i]/1000000.0))
|
total = nrj[i]/1000000000000.0
|
||||||
|
duration = (maximum[0]-minimum[0])/1000000.0
|
||||||
|
min_power = minimum[i]/1000000.0
|
||||||
|
max_power = maximum[i]/1000000.0
|
||||||
|
output = "Total nrj: %8.3f J for %s -- duration %8.3f sec -- min %8.3f W -- max %8.3f W\n"
|
||||||
|
self.fs.write(output.format(total, label[i], duration, min_power, max_power))
|
||||||
|
|
||||||
# store each AEP channel info except Platform in the results table
|
# store each AEP channel info except Platform in the results table
|
||||||
results_table[channel_name] = total_nrj, average_power
|
results_table[channel_name] = total_nrj, average_power
|
||||||
|
|
||||||
if (min[i] < offset[i]):
|
if minimum[i] < offset[i]:
|
||||||
self.fs.write ("!!! Min below offset\n")
|
self.fs.write("!!! Min below offset\n")
|
||||||
|
|
||||||
if duplicate[i]:
|
if duplicate[i]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
total += nrj[i]
|
total += nrj[i]
|
||||||
|
|
||||||
self.fs.write ("Total nrj: %8.3f J for %s -- duration %8.3f sec\n" % (total/1000000000000.0, "Platform ", (max[0]-min[0])/1000000.0))
|
output = "Total nrj: %8.3f J for Platform -- duration %8.3f sec\n"
|
||||||
|
self.fs.write(output.format(total/1000000000000.0, (maximum[0]-minimum[0])/1000000.0))
|
||||||
|
|
||||||
total_nrj = total/1000000000000.0
|
total_nrj = total/1000000000000.0
|
||||||
duration = (max[0]-min[0])/1000000.0
|
duration = (maximum[0]-minimum[0])/1000000.0
|
||||||
average_power = total_nrj/duration
|
average_power = total_nrj/duration
|
||||||
|
|
||||||
# store AEP Platform channel info in the results table
|
# store AEP Platform channel info in the results table
|
||||||
@ -405,11 +407,12 @@ class AepParser(object):
|
|||||||
|
|
||||||
return results_table
|
return results_table
|
||||||
|
|
||||||
|
# pylint: disable=too-many-branches,no-self-use,too-many-locals
|
||||||
def topology_from_config(self, topofile):
|
def topology_from_config(self, topofile):
|
||||||
try:
|
try:
|
||||||
ft = open(topofile, "r")
|
ft = open(topofile, "r")
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.warn('Unable to open config file {}'.format(topofile))
|
logger.warning('Unable to open config file {}'.format(topofile))
|
||||||
return
|
return
|
||||||
lines = ft.readlines()
|
lines = ft.readlines()
|
||||||
|
|
||||||
@ -451,10 +454,11 @@ class AepParser(object):
|
|||||||
topo[items[0]] = info
|
topo[items[0]] = info
|
||||||
|
|
||||||
# Increase index
|
# Increase index
|
||||||
index +=1
|
index += 1
|
||||||
|
|
||||||
|
|
||||||
# Create an entry for each virtual parent
|
# Create an entry for each virtual parent
|
||||||
|
# pylint: disable=consider-iterating-dictionary
|
||||||
for supply in topo.keys():
|
for supply in topo.keys():
|
||||||
# Parent is in the topology
|
# Parent is in the topology
|
||||||
parent = topo[supply]['parent']
|
parent = topo[supply]['parent']
|
||||||
@ -462,23 +466,25 @@ class AepParser(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if parent not in virtual:
|
if parent not in virtual:
|
||||||
virtual[parent] = { supply : topo[supply]['index'] }
|
virtual[parent] = {supply : topo[supply]['index']}
|
||||||
|
|
||||||
virtual[parent][supply] = topo[supply]['index']
|
virtual[parent][supply] = topo[supply]['index']
|
||||||
|
|
||||||
|
|
||||||
# Remove parent with 1 child as they don't give more information than their
|
# Remove parent with 1 child as they don't give more information than their
|
||||||
# child
|
# child
|
||||||
|
# pylint: disable=consider-iterating-dictionary
|
||||||
for supply in list(virtual.keys()):
|
for supply in list(virtual.keys()):
|
||||||
if len(virtual[supply]) == 1:
|
if len(virtual[supply]) == 1:
|
||||||
del virtual[supply];
|
del virtual[supply]
|
||||||
|
|
||||||
topo_list = ['']*(1+len(topo)+len(virtual))
|
topo_list = ['']*(1+len(topo)+len(virtual))
|
||||||
topo_list[0] = 'time'
|
topo_list[0] = 'time'
|
||||||
|
# pylint: disable=consider-iterating-dictionary
|
||||||
for chnl in topo.keys():
|
for chnl in topo.keys():
|
||||||
topo_list[topo[chnl]['index']] = chnl
|
topo_list[topo[chnl]['index']] = chnl
|
||||||
for chnl in virtual.keys():
|
for chnl in virtual.keys():
|
||||||
index +=1
|
index += 1
|
||||||
topo_list[index] = chnl
|
topo_list[index] = chnl
|
||||||
|
|
||||||
ft.close()
|
ft.close()
|
||||||
@ -490,6 +496,7 @@ class AepParser(object):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
def handleSigTERM(signum, frame):
|
def handleSigTERM(signum, frame):
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
@ -501,11 +508,11 @@ if __name__ == '__main__':
|
|||||||
ch.setLevel(logging.DEBUG)
|
ch.setLevel(logging.DEBUG)
|
||||||
logger.addHandler(ch)
|
logger.addHandler(ch)
|
||||||
|
|
||||||
infile = ""
|
in_file = ""
|
||||||
outfile = ""
|
out_file = ""
|
||||||
figurefile = ""
|
figurefile = ""
|
||||||
start = 0
|
start = 0
|
||||||
lenght = -1
|
length = -1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "i:vo:s:l:t:")
|
opts, args = getopt.getopt(sys.argv[1:], "i:vo:s:l:t:")
|
||||||
@ -515,22 +522,22 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o == "-i":
|
if o == "-i":
|
||||||
infile = a
|
in_file = a
|
||||||
if o == "-v":
|
if o == "-v":
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
if o == "-o":
|
if o == "-o":
|
||||||
parse = True
|
parse = True
|
||||||
outfile = a
|
out_file = a
|
||||||
if o == "-s":
|
if o == "-s":
|
||||||
start = int(float(a)*1000000)
|
start = int(float(a)*1000000)
|
||||||
if o == "-l":
|
if o == "-l":
|
||||||
lenght = int(float(a)*1000000)
|
length = int(float(a)*1000000)
|
||||||
if o == "-t":
|
if o == "-t":
|
||||||
topofile = a
|
topfile = a
|
||||||
parser = AepParser()
|
parser = AepParser()
|
||||||
print(parser.topology_from_config(topofile))
|
print(parser.topology_from_config(topfile))
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
parser = AepParser()
|
parser = AepParser()
|
||||||
parser.prepare(infile, outfile, figurefile)
|
parser.prepare(in_file, out_file, figurefile)
|
||||||
parser.parse_aep(start, lenght)
|
parser.parse_aep(start, length)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user