config.pl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #!/usr/bin/env perl
  2. #
  3. # Copyright The Mbed TLS Contributors
  4. # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  5. #
  6. # This file is provided under the Apache License 2.0, or the
  7. # GNU General Public License v2.0 or later.
  8. #
  9. # **********
  10. # Apache License 2.0:
  11. #
  12. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  13. # not use this file except in compliance with the License.
  14. # You may obtain a copy of the License at
  15. #
  16. # http://www.apache.org/licenses/LICENSE-2.0
  17. #
  18. # Unless required by applicable law or agreed to in writing, software
  19. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  20. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. # See the License for the specific language governing permissions and
  22. # limitations under the License.
  23. #
  24. # **********
  25. #
  26. # **********
  27. # GNU General Public License v2.0 or later:
  28. #
  29. # This program is free software; you can redistribute it and/or modify
  30. # it under the terms of the GNU General Public License as published by
  31. # the Free Software Foundation; either version 2 of the License, or
  32. # (at your option) any later version.
  33. #
  34. # This program is distributed in the hope that it will be useful,
  35. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37. # GNU General Public License for more details.
  38. #
  39. # You should have received a copy of the GNU General Public License along
  40. # with this program; if not, write to the Free Software Foundation, Inc.,
  41. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  42. #
  43. # **********
  44. #
  45. # Purpose
  46. #
  47. # Comments and uncomments #define lines in the given header file and optionally
  48. # sets their value or can get the value. This is to provide scripting control of
  49. # what preprocessor symbols, and therefore what build time configuration flags
  50. # are set in the 'config.h' file.
  51. #
  52. # Usage: config.pl [-f <file> | --file <file>] [-o | --force]
  53. # [set <symbol> <value> | unset <symbol> | get <symbol> |
  54. # full | realfull]
  55. #
  56. # Full usage description provided below.
  57. #
  58. # The following options are disabled instead of enabled with "full".
  59. #
  60. # * Options that require additional build dependencies or unusual hardware.
  61. # * Options that make testing less effective.
  62. # * Options that are incompatible with other options, or more generally that
  63. # interact with other parts of the code in such a way that a bulk enabling
  64. # is not a good way to test them.
  65. # * Options that remove features.
  66. #
  67. # The baremetal configuration excludes options that require a library or
  68. # operating system feature that is typically not present on bare metal
  69. # systems. It also excludes debugging features that increase the code size
  70. # of other modules.
  71. # Features that are excluded from "full" won't be in "baremetal" either.
  72. use warnings;
  73. use strict;
  74. my $config_file = "include/mbedtls/config.h";
  75. my $usage = <<EOU;
  76. $0 [-f <file> | --file <file>] [-o | --force]
  77. [set <symbol> <value> | unset <symbol> | get <symbol> |
  78. full | realfull | baremetal]
  79. Commands
  80. set <symbol> [<value>] - Uncomments or adds a #define for the <symbol> to
  81. the configuration file, and optionally making it
  82. of <value>.
  83. If the symbol isn't present in the file an error
  84. is returned.
  85. unset <symbol> - Comments out the #define for the given symbol if
  86. present in the configuration file.
  87. get <symbol> - Finds the #define for the given symbol, returning
  88. an exitcode of 0 if the symbol is found, and 1 if
  89. not. The value of the symbol is output if one is
  90. specified in the configuration file.
  91. full - Uncomments all #define's in the configuration file
  92. excluding some reserved symbols, until the
  93. 'Module configuration options' section
  94. realfull - Uncomments all #define's with no exclusions
  95. baremetal - Sets full configuration suitable for baremetal build.
  96. Options
  97. -f | --file <filename> - The file or file path for the configuration file
  98. to edit. When omitted, the following default is
  99. used:
  100. $config_file
  101. -o | --force - If the symbol isn't present in the configuration
  102. file when setting its value, a #define is
  103. appended to the end of the file.
  104. EOU
  105. my @excluded = qw(
  106. MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
  107. MBEDTLS_DEPRECATED_REMOVED
  108. MBEDTLS_DEPRECATED_WARNING
  109. MBEDTLS_ECP_NO_INTERNAL_RNG
  110. MBEDTLS_HAVE_SSE2
  111. MBEDTLS_MEMORY_BACKTRACE
  112. MBEDTLS_MEMORY_BUFFER_ALLOC_C
  113. MBEDTLS_MEMORY_DEBUG
  114. MBEDTLS_NO_64BIT_MULTIPLICATION
  115. MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
  116. MBEDTLS_NO_PLATFORM_ENTROPY
  117. MBEDTLS_NO_UDBL_DIVISION
  118. MBEDTLS_PKCS11_C
  119. MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
  120. MBEDTLS_REMOVE_3DES_CIPHERSUITES
  121. MBEDTLS_REMOVE_ARC4_CIPHERSUITES
  122. MBEDTLS_RSA_NO_CRT
  123. MBEDTLS_SSL_HW_RECORD_ACCEL
  124. MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
  125. MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
  126. MBEDTLS_TEST_NULL_ENTROPY
  127. MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
  128. MBEDTLS_ZLIB_SUPPORT
  129. _ALT\s*$
  130. );
  131. # Things that should be disabled in "baremetal"
  132. my @excluded_baremetal = qw(
  133. MBEDTLS_DEBUG_C
  134. MBEDTLS_ENTROPY_NV_SEED
  135. MBEDTLS_FS_IO
  136. MBEDTLS_HAVEGE_C
  137. MBEDTLS_HAVE_TIME
  138. MBEDTLS_HAVE_TIME_DATE
  139. MBEDTLS_MEMORY_BACKTRACE
  140. MBEDTLS_MEMORY_BUFFER_ALLOC_C
  141. MBEDTLS_NET_C
  142. MBEDTLS_PLATFORM_FPRINTF_ALT
  143. MBEDTLS_PLATFORM_NV_SEED_ALT
  144. MBEDTLS_PLATFORM_TIME_ALT
  145. MBEDTLS_TEST_HOOKS
  146. MBEDTLS_THREADING_C
  147. MBEDTLS_THREADING_PTHREAD
  148. MBEDTLS_TIMING_C
  149. );
  150. # Things that should be enabled in "full" even if they match @excluded.
  151. # Platform ALTs enable global variables that allow configuring the behavior
  152. # but default to the default behavior, except for PLATFORM_SETUP_TEARDOWN_ALT
  153. # which requires the application to provide relevant functions like
  154. # non-platform ALTs.
  155. my @non_excluded = qw(
  156. PLATFORM_(?!SETUP_TEARDOWN_)[A-Z_0-9]+_ALT
  157. );
  158. # Things that should be enabled in "baremetal"
  159. my @non_excluded_baremetal = qw(
  160. MBEDTLS_NO_PLATFORM_ENTROPY
  161. );
  162. # Process the command line arguments
  163. my $force_option = 0;
  164. my ($arg, $name, $value, $action);
  165. while ($arg = shift) {
  166. # Check if the argument is an option
  167. if ($arg eq "-f" || $arg eq "--file") {
  168. $config_file = shift;
  169. -f $config_file or die "No such file: $config_file\n";
  170. }
  171. elsif ($arg eq "-o" || $arg eq "--force") {
  172. $force_option = 1;
  173. }
  174. else
  175. {
  176. # ...else assume it's a command
  177. $action = $arg;
  178. if ($action eq "full" || $action eq "realfull" || $action eq "baremetal" ) {
  179. # No additional parameters
  180. die $usage if @ARGV;
  181. }
  182. elsif ($action eq "unset" || $action eq "get") {
  183. die $usage unless @ARGV;
  184. $name = shift;
  185. }
  186. elsif ($action eq "set") {
  187. die $usage unless @ARGV;
  188. $name = shift;
  189. $value = shift if @ARGV;
  190. }
  191. else {
  192. die "Command '$action' not recognised.\n\n".$usage;
  193. }
  194. }
  195. }
  196. # If no command was specified, exit...
  197. if ( not defined($action) ){ die $usage; }
  198. # Check the config file is present
  199. if (! -f $config_file) {
  200. chdir '..' or die;
  201. # Confirm this is the project root directory and try again
  202. if ( !(-d 'scripts' && -d 'include' && -d 'library' && -f $config_file) ) {
  203. die "If no file specified, must be run from the project root or scripts directory.\n";
  204. }
  205. }
  206. # Now read the file and process the contents
  207. open my $config_read, '<', $config_file or die "read $config_file: $!\n";
  208. my @config_lines = <$config_read>;
  209. close $config_read;
  210. # Add required baremetal symbols to the list that is included.
  211. if ( $action eq "baremetal" ) {
  212. @non_excluded = ( @non_excluded, @non_excluded_baremetal );
  213. }
  214. my ($exclude_re, $no_exclude_re, $exclude_baremetal_re);
  215. if ($action eq "realfull") {
  216. $exclude_re = qr/^$/;
  217. $no_exclude_re = qr/./;
  218. } else {
  219. $exclude_re = join '|', @excluded;
  220. $no_exclude_re = join '|', @non_excluded;
  221. }
  222. if ( $action eq "baremetal" ) {
  223. $exclude_baremetal_re = join '|', @excluded_baremetal;
  224. }
  225. my $config_write = undef;
  226. if ($action ne "get") {
  227. open $config_write, '>', $config_file or die "write $config_file: $!\n";
  228. }
  229. my $done;
  230. for my $line (@config_lines) {
  231. if ($action eq "full" || $action eq "realfull" || $action eq "baremetal" ) {
  232. if ($line =~ /name SECTION: Module configuration options/) {
  233. $done = 1;
  234. }
  235. if (!$done && $line =~ m!^//\s?#define! &&
  236. ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) &&
  237. ( $action ne "baremetal" || ( $line !~ /$exclude_baremetal_re/ ) ) ) {
  238. $line =~ s!^//\s?!!;
  239. }
  240. if (!$done && $line =~ m!^\s?#define! &&
  241. ! ( ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) &&
  242. ( $action ne "baremetal" || ( $line !~ /$exclude_baremetal_re/ ) ) ) ) {
  243. $line =~ s!^!//!;
  244. }
  245. } elsif ($action eq "unset") {
  246. if (!$done && $line =~ /^\s*#define\s*$name\b/) {
  247. $line = '//' . $line;
  248. $done = 1;
  249. }
  250. } elsif (!$done && $action eq "set") {
  251. if ($line =~ m!^(?://)?\s*#define\s*$name\b!) {
  252. $line = "#define $name";
  253. $line .= " $value" if defined $value && $value ne "";
  254. $line .= "\n";
  255. $done = 1;
  256. }
  257. } elsif (!$done && $action eq "get") {
  258. if ($line =~ /^\s*#define\s*$name(?:\s+(.*?))\s*(?:$|\/\*|\/\/)/) {
  259. $value = $1;
  260. $done = 1;
  261. }
  262. }
  263. if (defined $config_write) {
  264. print $config_write $line or die "write $config_file: $!\n";
  265. }
  266. }
  267. # Did the set command work?
  268. if ($action eq "set" && $force_option && !$done) {
  269. # If the force option was set, append the symbol to the end of the file
  270. my $line = "#define $name";
  271. $line .= " $value" if defined $value && $value ne "";
  272. $line .= "\n";
  273. $done = 1;
  274. print $config_write $line or die "write $config_file: $!\n";
  275. }
  276. if (defined $config_write) {
  277. close $config_write or die "close $config_file: $!\n";
  278. }
  279. if ($action eq "get") {
  280. if ($done) {
  281. if ($value ne '') {
  282. print "$value\n";
  283. }
  284. exit 0;
  285. } else {
  286. # If the symbol was not found, return an error
  287. exit 1;
  288. }
  289. }
  290. if ($action eq "full" && !$done) {
  291. die "Configuration section was not found in $config_file\n";
  292. }
  293. if ($action ne "full" && $action ne "unset" && !$done) {
  294. die "A #define for the symbol $name was not found in $config_file\n";
  295. }
  296. __END__