list_unintended_exported_symbols: export public symbols list.

This list could be used for namespacing as follows (using existing
prototype scripts that do a bit more than what we actually will need in
the end):

```
$ util/list_unintended_exported_symbols.sh
$ cmake -GNinja -B build -DBORINGSSL_PREFIX=brlogenshfegle -DBORINGSSL_PREFIX_SYMBOLS=$PWD/include.syms
$ ninja -C build
$ nm --defined-only --extern-only --format=just-symbols --demangle build/libcrypto.a | grep -v brlogenshfegle | grep -v ^std:: | grep -v \.o: | grep . | less
```

Note that this does not yet cover asm defined symbols.

Bug: 42220000
Change-Id: I6ea9d50f164ba420f52e32b83d97b2ebfd8d6066
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/86428
Reviewed-by: Xiangfei Ding <xfding@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
diff --git a/util/extract_identifiers_clang_json.go b/util/extract_identifiers_clang_json.go
index d6db5ea..d7cf27a 100644
--- a/util/extract_identifiers_clang_json.go
+++ b/util/extract_identifiers_clang_json.go
@@ -39,10 +39,11 @@
 )
 
 var (
-	dumpTree     = flag.Bool("dump_tree", false, "dump syntax tree while processing")
-	dumpFullTree = flag.Bool("dump_full_tree", false, "dump syntax tree while processing including system headers")
-	keepGoing    = flag.Bool("keep_going", false, "continue even after errors")
-	language     = flag.String("language", "C", "language to consider the source to be")
+	dumpTree          = flag.Bool("dump_tree", false, "dump syntax tree while processing")
+	dumpFullTree      = flag.Bool("dump_full_tree", false, "dump syntax tree while processing including system headers")
+	keepGoing         = flag.Bool("keep_going", false, "continue even after errors")
+	language          = flag.String("language", "C", "language to consider the source to be")
+	globalSymbolsOnly = flag.Bool("global_symbols_only", false, "only output a list of names that may become (part of) linker symbols and are not namespaced")
 )
 
 // node is a node from the Clang AST dump.
@@ -543,22 +544,25 @@
 		case staticStorage:
 			linkage = "static "
 		default:
-			return fmt.Errorf("respecting storage, but storage not set for %v", fqn)
+			return fmt.Errorf("respecting linkage, but storage not set for %v", fqn)
 		}
 	}
 
-	var identifier string
+	var namespaced bool
 	switch namespacing {
 	case alwaysGlobal:
-		identifier = name
+		namespaced = false
 	case globalIfC:
-		if w.language == "C++" {
-			identifier = fqn
-		} else {
-			identifier = name
-		}
+		namespaced = w.language == "C++"
 	case alwaysNamespaced:
+		namespaced = true
+	}
+
+	var identifier string
+	if namespaced {
 		identifier = fqn
+	} else {
+		identifier = name
 	}
 
 	declaration := fmt.Sprintf("%s%s %s;", linkage, tag, identifier)
@@ -572,6 +576,13 @@
 	}
 	w.seen[key] = declaration
 
+	if *globalSymbolsOnly {
+		if !namespaced && storage != staticStorage {
+			fmt.Printf("%s\n", identifier)
+		}
+		return nil
+	}
+
 	// Append some debug info.
 	// This might be used later to generate symbol renaming headers,
 	// but is generally useful to humans debugging this tool's output.
diff --git a/util/list_unintended_exported_symbols.sh b/util/list_unintended_exported_symbols.sh
index 0286372..deb043b 100755
--- a/util/list_unintended_exported_symbols.sh
+++ b/util/list_unintended_exported_symbols.sh
@@ -55,10 +55,18 @@
 	source_to_ast -x c -std=c17 "$@" | ast_to_identifiers --language=C
 }
 
+c_source_to_symbols() {
+	source_to_ast -x c -std=c17 "$@" | ast_to_identifiers --language=C --global_symbols_only
+}
+
 cc_source_to_identifiers() {
 	source_to_ast -x c++ -std=c++17 "$@" | ast_to_identifiers --language=C++
 }
 
+cc_source_to_symbols() {
+	source_to_ast -x c++ -std=c++17 "$@" | ast_to_identifiers --language=C++ --global_symbols_only
+}
+
 lib_sources() {
 	jq  -r '
 			[.bcm, .crypto, .decrepit] |
@@ -155,17 +163,21 @@
 
 echo >&2 'Indexing C++ includes...'
 include_files $(public_cc_includes) | cc_source_to_identifiers - > include.cc.ids
+include_files $(public_cc_includes) | cc_source_to_symbols - > include.cc.syms
 echo >&2 'Indexing C includes...'
 include_files $(public_c_includes) | c_source_to_identifiers - > include.c.ids
+include_files $(public_c_includes) | c_source_to_symbols - > include.c.syms
 echo >&2 'Indexing C includes as C++...'
 include_files $(public_c_includes) | cc_source_to_identifiers - > include.c_as_cc.ids
+include_files $(public_c_includes) | cc_source_to_symbols - > include.c_as_cc.syms
+echo >&2 'Merging symbol lists...'
+cat include.c.syms include.cc.syms include.c_as_cc.syms | sort -u > include.syms
 
 # Check that the headers behave the same if included by C and C++ files, other
 # than for expected diffs.
 echo >&2 'Comparing C includes across including language...'
 fix_c_cc_include_deltas < include.c.ids > include.c.common.ids
 fix_c_cc_include_deltas < include.c_as_cc.ids > include.c_as_cc.common.ids
-diff -u include.c.common.ids include.c_as_cc.common.ids >&2
 
 # Check that no source file defines any public symbols that are not in the
 # public headers, namespaced or otherwise OK'd.