3 # Quick and dirty utility to help assemble the mandated (but otherwise
4 # useless) API documentation. We get the list of external function
5 # symbols from fipscanister.o, pair those with the source file names
6 # (from ./fips/fipssyms.h), and map to the object file name containing
9 # Requires the "nm" and "find" utilities.
10 # Execure from the root of the FIPS module source code workarea
16 require "$here/api_fns.pm";
18 $_direction_question = ''; # Set to '?' to show "<-?", "<->?" for uncertain directions
20 print STDERR "Info: finding FIPS renames and reimplementations of OpenSSL symbols\n";
21 # Get mapping of old (source code) to new (live as renamed) symbols
22 foreach $file ("./fips/fipssyms.h") {
23 open(IN, $file) || die "Error opening $file";
24 # grab pairs until assembler symbols
26 my $reimplementations = 1; # When 1, we're looking at reimplementations
27 # (not renames) of OpenSSL functions. They
28 # still have to be saved to get the API.
30 $reimplementations = 0 if m|^\s*/\*\sRename\ssymbols\s|;
41 ($oldname, $newname) = m/#define\s+(\S+)\(.*\)\s+(\S+)\(.*\)/;
43 ($oldname, $newname) = m/#define\s+(\S+)\s+(\S+)/;
47 if (!$reimplementations) {
48 $oldname{$newname} = $oldname;
50 $oldimpl{$newname} = $oldname;
54 # %oldname is the mapping of new function names to old
55 print "<!-- Total of ", scalar(keys %oldname), " mapped symbols in $file -->\n";
58 print STDERR "Info: finding FIPS symbols in object files\n";
59 # generate list of external function names in fipscanister.o
60 $file = "./fips/fipscanister.o";
61 for (`nm -g --defined-only -p -o $file`) {
66 $objname =~ s/\.o$/\.\[o\|c\]/;
67 $objname{$symname} = $objname;
69 # keys %fipssyms is the list of module functions
70 print "<!-- Total of ", scalar(keys %fipssyms), " functions in $file -->\n";
72 # grab filename to symbol name mapping, each line is of the format
73 # ./fips/sha/fips_sha1_selftest.o:00000000 T FIPS_selftest_sha1
74 # discard the offset and type ":00000000 T".
75 for (`find . -name '*.o' \\! -name 'fipscanister.o' -exec nm -g --defined-only -p -o {} \\;`) {
76 ($objname, $symname) = m/^(\S+):\S+\s+T+\s+(\S+)/;
78 # $fipssyms{$symname} || next;
79 $objname =~ s/\.o$/\.\[o\|c\]/;
80 $objname{$symname} = $objname;
82 # %objname is the mapping of new symbol name to (source/object) file name
83 print "<!-- Total of ", scalar(keys %objname), " functions found in files -->\n";
85 print STDERR "Info: finding declarations in header files\n";
87 # grab filenames in include/openssl, run each of them through
88 # get_function_declarations_from_file (defined in api_fns.pl)
89 # and collect the result.
91 while (<include/openssl/*.h ./crypto/cryptlib.h>) {
92 my %decls = api_data::get_function_declaration_strings_from_file($_);
93 map { $declarations{$_} = $decls{$_} } keys %decls;
95 # %declarations is the mapping of old symbol name to their declaration
96 print "<!-- Total of ", scalar(keys %declarations), " declarations found in header files -->\n";
98 # Add the markers FIPS_text_start and FIPS_text_end
99 $declarations{FIPS_text_start} = "void *FIPS_text_start()";
100 $declarations{FIPS_text_end} = "void *FIPS_text_end()";
103 # Read list of API names obtained from edited "nm -g fipscanister.o"
107 if ($_->{kind} >= 0) {
110 print "kind: ",$_->{kind} ? "function" : "variable","\n";
112 print "sym: ",$_->{sym},"\n";
114 print "type: ",$_->{type},"\n";
121 printf "param %d:\n", ++$c;
125 my $direction = $_->{direction};
126 if (!$_direction_question) {
127 $direction =~ s/<-\? <->\?/<->/;
128 $direction =~ s/\?//g;
130 print " " x $indent,$direction," ",$_->{sym},"\n";
133 if ($_->{type} !~ m/^\s*void\s*$/) {
141 print "decl: ",$_->{decl},"\n";
148 my $print_mode = shift; # 0 = print declaration with symbol in bold,
149 # call recursively with 1 for each parameter,
150 # call recursively with 2 for each parameter
151 # 1 = print declaration with sym grey background,
152 # call recursivelt with 3 for each parameter
153 # 2 = just print declaration
154 my $d = shift; # Parsed declaration
157 if ($print_mode == 0) {
158 $d->{sym} || return $s;
159 my $h = "<hr><br />\n";
160 $h .= $d->{sym} . ($d->{symcomment} ? " " . $d->{symcomment} : "");
161 $h .= " in file " . $d->{objfile} . "<br />\n<br />\n";
163 $s .= '<b>' . $d->{sym} . '</b>';
164 if ($d->{kind} == 1) {
175 if ($d->{kind} == 1) {
177 my $direction = $_->{direction};
178 if (!$_direction_question) {
179 $direction =~ s/<-\? <->\?/<->/;
180 $direction =~ s/\?//g;
183 $s .= encode_entities($direction
184 . "\xA0" x (9 - length($direction)));
188 if ($d->{type} !~ m/^\s*void\s*\?$/) {
190 $s .= encode_entities('<-'.("\xA0" x 7).'Return');
193 } elsif ($print_mode == 1) {
194 $s .= '<span style="background: #c0c0c0">' . $d->{sym} . '</span>';
195 if ($d->{kind} == 1) {
206 } elsif ($print_mode == 2) {
208 if ($d->{kind} == 1) {
223 print STDERR "Info: building/updating symbol information database\n";
225 $d = api_data->new();
226 if (-s "$here/declarations.dat") {
227 $d->read_declaration_db("$here/declarations.dat");
229 print STDERR "Warning: there was no file '$here/declarations.dat'. A new one will be created\n";
232 for (sort keys %fipssyms) {
234 $namecomment = undef;
235 if ($oldname{$newname}) {
236 $oldname = $oldname{$newname};
237 $objname = $objname{$oldname} ? $objname{$oldname} : $objname{$newname};
238 $namecomment = "(renames $oldname)";
240 $objname = $objname{$newname};
242 if ($oldimpl{$newname}) {
243 $apisym = $oldimpl{$newname};
244 $namecomment = "(reimplements $apisym)" if !$namecomment;
248 $declaration = $declarations{$apisym};
250 print "$newname\t\t$namecomment\tin file $objname:\n";
251 print " ",$declaration,"\n ";
252 $d->add_declaration($declaration,$newname,$objname,$namecomment);
256 $d->complete_directions();
257 $d->write_declaration_db("$here/declarations.dat");
259 print STDERR "Info: printing output\n";
261 $d->on_all_declarations(
265 #print printer($decl);
266 print "<p>",html_printer(0,$decl),"</p>\n";