1# Generate dl-tunable-list.h from dl-tunables.list
2
3BEGIN {
4  min_of["STRING"]="0"
5  max_of["STRING"]="0"
6  min_of["INT_32"]="INT32_MIN"
7  max_of["INT_32"]="INT32_MAX"
8  min_of["UINT_64"]="0"
9  max_of["UINT_64"]="UINT64_MAX"
10  min_of["SIZE_T"]="0"
11  max_of["SIZE_T"]="SIZE_MAX"
12  tunable=""
13  ns=""
14  top_ns=""
15  max_name_len=0
16  max_alias_len=0
17}
18
19# Skip over blank lines and comments.
20/^#/ {
21  next
22}
23
24/^[ \t]*$/ {
25  next
26}
27
28# Beginning of either a top namespace, tunable namespace or a tunable, decided
29# on the current value of TUNABLE, NS or TOP_NS.
30$2 == "{" {
31  if (top_ns == "") {
32    top_ns = $1
33  }
34  else if (ns == "") {
35    ns = $1
36  }
37  else if (tunable == "") {
38    tunable = $1
39  }
40  else {
41    printf ("Unexpected occurrence of '{': %s:%d\n", FILENAME, FNR)
42    exit 1
43  }
44
45  next
46}
47
48# End of either a top namespace, tunable namespace or a tunable.
49$1 == "}" {
50  if (tunable != "") {
51    # Tunables definition ended, now fill in default attributes.
52    if (!types[top_ns,ns,tunable]) {
53      types[top_ns,ns,tunable] = "STRING"
54    }
55    if (!minvals[top_ns,ns,tunable]) {
56      minvals[top_ns,ns,tunable] = min_of[types[top_ns,ns,tunable]]
57    }
58    if (!maxvals[top_ns,ns,tunable]) {
59      maxvals[top_ns,ns,tunable] = max_of[types[top_ns,ns,tunable]]
60    }
61    if (!env_alias[top_ns,ns,tunable]) {
62      env_alias[top_ns,ns,tunable] = "{0}"
63    }
64    if (!security_level[top_ns,ns,tunable]) {
65      security_level[top_ns,ns,tunable] = "SXID_ERASE"
66    }
67    len = length(top_ns"."ns"."tunable)
68    if (len > max_name_len)
69      max_name_len = len
70
71    tunable = ""
72  }
73  else if (ns != "") {
74    ns = ""
75  }
76  else if (top_ns != "") {
77    top_ns = ""
78  }
79  else {
80    printf ("syntax error: extra }: %s:%d\n", FILENAME, FNR)
81    exit 1
82  }
83  next
84}
85
86# Everything else, which could either be a tunable without any attributes or a
87# tunable attribute.
88{
89  if (ns == "") {
90    printf("Line %d: Invalid tunable outside a namespace: %s\n", NR, $0)
91    exit 1
92  }
93
94  if (tunable == "") {
95    # We encountered a tunable without any attributes, so note it with a
96    # default.
97    types[top_ns,ns,$1] = "STRING"
98    next
99  }
100
101  # Otherwise, we have encountered a tunable attribute.
102  split($0, arr, ":")
103  attr = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[1])
104  val = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[2])
105
106  if (attr == "type") {
107    types[top_ns,ns,tunable] = val
108  }
109  else if (attr == "minval") {
110    minvals[top_ns,ns,tunable] = val
111  }
112  else if (attr == "maxval") {
113    maxvals[top_ns,ns,tunable] = val
114  }
115  else if (attr == "env_alias") {
116    env_alias[top_ns,ns,tunable] = sprintf("\"%s\"", val)
117    len = length(val)
118    if (len > max_alias_len)
119      max_alias_len = len
120  }
121  else if (attr == "security_level") {
122    if (val == "SXID_ERASE" || val == "SXID_IGNORE" || val == "NONE") {
123      security_level[top_ns,ns,tunable] = val
124    }
125    else {
126      printf("Line %d: Invalid value (%s) for security_level: %s, ", NR, val,
127	     $0)
128      print("Allowed values are 'SXID_ERASE', 'SXID_IGNORE', or 'NONE'")
129      exit 1
130    }
131  }
132  else if (attr == "default") {
133    if (types[top_ns,ns,tunable] == "STRING") {
134      default_val[top_ns,ns,tunable] = sprintf(".strval = \"%s\"", val);
135    }
136    else {
137      default_val[top_ns,ns,tunable] = sprintf(".numval = %s", val)
138    }
139  }
140}
141
142END {
143  if (ns != "") {
144    print "Unterminated namespace.  Is a closing brace missing?"
145    exit 1
146  }
147
148  print "/* AUTOGENERATED by gen-tunables.awk.  */"
149  print "#ifndef _TUNABLES_H_"
150  print "# error \"Do not include this file directly.\""
151  print "# error \"Include tunables.h instead.\""
152  print "#endif"
153  print "#include <dl-procinfo.h>\n"
154
155  # Now, the enum names
156  print "\ntypedef enum"
157  print "{"
158  for (tnm in types) {
159    split (tnm, indices, SUBSEP);
160    t = indices[1];
161    n = indices[2];
162    m = indices[3];
163    printf ("  TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m);
164  }
165  print "} tunable_id_t;\n"
166
167  print "\n#ifdef TUNABLES_INTERNAL"
168  # Internal definitions.
169  print "# define TUNABLE_NAME_MAX " (max_name_len + 1)
170  print "# define TUNABLE_ALIAS_MAX " (max_alias_len + 1)
171  print "# include \"dl-tunable-types.h\""
172  # Finally, the tunable list.
173  print "static tunable_t tunable_list[] attribute_relro = {"
174  for (tnm in types) {
175    split (tnm, indices, SUBSEP);
176    t = indices[1];
177    n = indices[2];
178    m = indices[3];
179    printf ("  {TUNABLE_NAME_S(%s, %s, %s)", t, n, m)
180    printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, NULL, TUNABLE_SECLEVEL_%s, %s},\n",
181	    types[t,n,m], minvals[t,n,m], maxvals[t,n,m],
182	    default_val[t,n,m], security_level[t,n,m], env_alias[t,n,m]);
183  }
184  print "};"
185  print "#endif"
186}
187