# BST-TIMEOUT: 120 # 16s / 15s / 16s for all 189 cases on the staged glibc image # # (2026-08-19, local-verify, build host also running a second # # Yocto build -- so a loaded-host figure already). That fits # # the runner's own 60 s default; the marker is 7.5x the # # measurement rather than 2x it, because the reads here are # # whole-file and their cost tracks how large abseil's headers # # and archives get, not how many cases this file declares. . "$BST_LIB" # abseil-cpp 20240116.3 -- Google's base C++ library, and the FIRST ticket of the # C++ round (BRINTOS-1094): re2 and protobuf both DEPEND on it. See # recipes-devtools/abseil-cpp/abseil-cpp_%.bbappend for what the port adds. # # The distro is static-only and there is no on-target C++ compiler, so the whole # on-target assertion is that the shipped payload is real and is what this port # meant to ship: 350 headers with their declared surface and the LTS/ABI macros # every consumer's mangling depends on; 185 per-component pkg-config files and a # CMake package that names 86 STATIC archives and no shared object; and the # archives themselves carrying their compiled members, ITANIUM-MANGLED symbols, # and the vtable/typeinfo records no C compile can emit. # # It also pins THIS PORT'S FIVE PATCHES, which is what separates this suite from # a generic "the files are there" check. Three of them are visible on target: # two in shipped headers (the wasm32 mmap branch, the threadless stdcpp-waiter # guard) and one in the symbol table (StdcppWaiter compiled away while # FutexWaiter is the waiter that survived). If any stops applying, the build # still succeeds and only these cases go red. # # --------------------------------------------------------------------------- # EXEC BUDGET -- WHY THIS FILE LOOKS THE WAY IT DOES # # The cost here is execs, not cases. Every exec on this guest is a fresh wasm # module instantiation of a multi-megabyte static binary, and the first draft of # this suite -- which spent one `cat` per header needle and one `grep` per # symbol, ~200 execs for ~190 cases -- got 53 cases done in 600 s and was killed # by its own bound. Measured on the same image: ~20 s per exec, and essentially # zero for anything the shell does itself. # # So the rule for this file is ONE EXEC PER FILE, NEVER ONE PER CASE: # # * text files are read once with `slurp` and every needle against them is a # `case` match in the shell, so a header asserted twelve times costs one # exec, not twelve; # * each archive is flattened once with `tr` and matched once with a single # `grep -F -f` over a pattern file, so nine archives cost eighteen execs # rather than one per symbol; # * presence, counts and the no-shared/no-libtool assertions use `test` and # shell globs, which are builtins. # # That is ~18 execs for ~190 cases. If you add a needle, add it to an existing # pattern list; if you add a `cat`, `ls` or `grep` you have added ~20 s. inc=/usr/include/absl pc=/usr/lib/pkgconfig cmk=/usr/lib/cmake/absl lib=/usr/lib # slurp -> $SLURP. # # `$(cat "$1")` and NOT a `while read` loop redirected from the file, which is # what this started as and is cheaper. The README's rule is the reason: a # top-level stdin redirect from a file on the virtiofs root makes dup2(2) return # the kernel's restart park sentinel 513, ash treats the failed redirect as # fatal and exits, and the suite ends mid-run while the runner reports every # case that did emit as a pass -- brintos/linux#73, measured there at 20/20 on # the rootfs against 0/20 from /tmp. Passing the file as an ARGUMENT performs no # redirect at all, which is why `cat`/`head` are unaffected by that defect where # `prog < file` is not. # # The read-loop form survived 69 rootfs reads across three on-target runs here, # so this is not a bug being fixed -- it is a documented shape not being relied # on for an intermittent failure that would be invisible when it did bite. slurp() { SLURP_NAME=$1 SLURP=$(cat "$1") } # has : substring assertion against the last slurped file. has() { case "$SLURP" in *"$2"*) bst_ok "$1" ;; *) bst_notok "$1" "not in ${SLURP_NAME##*/}: $2" ;; esac } if [ ! -f "$inc/base/config.h" ]; then bst_skip abseil-cpp/present "abseil-cpp-dev not installed on this image" exit 0 fi bst_ok abseil-cpp/present # A converted abseil ships libabsl_*.so and no archive (one BUILD_SHARED_LIBS). CONVERTED=0 bst_ps_converted "$lib/libabsl_base.so" "$lib/libabsl_base.so.*" && CONVERTED=1 # --------------------------------------------------------------------------- # 1. The header tree. One per component so a partial -dev install is visible. # `test -s` is a builtin, so these 25 cases are free. # The `:` pairs are spelled out rather than derived, because # deriving one from the other means an exec per iteration -- POSIX parameter # expansion cannot replace a '/', and a case id may not carry a second one. for hp in base/config.h:base-config base/options.h:base-options \ strings/str_cat.h:strings-str-cat strings/string_view.h:strings-string-view \ strings/cord.h:strings-cord status/status.h:status-status \ status/statusor.h:status-statusor synchronization/mutex.h:sync-mutex \ synchronization/notification.h:sync-notification time/time.h:time-time \ time/clock.h:time-clock time/civil_time.h:time-civil-time \ container/flat_hash_map.h:container-flat-hash-map \ container/inlined_vector.h:container-inlined-vector \ types/optional.h:types-optional types/span.h:types-span \ numeric/int128.h:numeric-int128 hash/hash.h:hash-hash \ debugging/stacktrace.h:debugging-stacktrace \ debugging/symbolize.h:debugging-symbolize flags/flag.h:flags-flag \ log/log.h:log-log random/random.h:random-random crc/crc32c.h:crc-crc32c \ functional/any_invocable.h:functional-any-invocable; do check "abseil-cpp/hdr-${hp#*:}" test -s "$inc/${hp%%:*}" done # 2. The LTS identity, which is not decoration: ABSL_OPTION_INLINE_NAMESPACE_NAME # is spelled into EVERY mangled symbol below as `12lts_20240116`, so a version # bump changes the whole ABI and every symbol case in this file with it. slurp "$inc/base/config.h" has abseil-cpp/lts-version "#define ABSL_LTS_RELEASE_VERSION 20240116" has abseil-cpp/lts-patch "#define ABSL_LTS_RELEASE_PATCH_LEVEL 3" slurp "$inc/base/options.h" has abseil-cpp/lts-inline "#define ABSL_OPTION_USE_INLINE_NAMESPACE 1" has abseil-cpp/lts-nsname "#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20240116" # The four std-aliasing options. All 1 -- always the std type, never abseil's # own -- which is what makes C++17 a hard requirement of this configuration # rather than a preference, and is why the recipe states the standard. has abseil-cpp/opt-std-any "#define ABSL_OPTION_USE_STD_ANY 1" has abseil-cpp/opt-std-optional "#define ABSL_OPTION_USE_STD_OPTIONAL 1" has abseil-cpp/opt-std-string-view "#define ABSL_OPTION_USE_STD_STRING_VIEW 1" has abseil-cpp/opt-std-variant "#define ABSL_OPTION_USE_STD_VARIANT 1" slurp "$inc/strings/string_view.h" has abseil-cpp/string-view-is-std "using string_view = std::string_view;" # 3. The declared surface, sampled across the components the port names. slurp "$inc/strings/str_cat.h" has abseil-cpp/api-strcat "std::string StrCat(" has abseil-cpp/api-strappend "void StrAppend(" slurp "$inc/status/status.h" has abseil-cpp/api-status "class ABSL_ATTRIBUTE_TRIVIAL_ABI Status" has abseil-cpp/api-statuscode "enum class StatusCode : int" has abseil-cpp/api-statusfns "Status InternalError(" slurp "$inc/status/statusor.h" has abseil-cpp/api-badstatus "class BadStatusOrAccess" slurp "$inc/synchronization/mutex.h" has abseil-cpp/api-mutex "class ABSL_LOCKABLE Mutex {" has abseil-cpp/api-condvar "class CondVar" has abseil-cpp/api-mutexlock "class ABSL_SCOPED_LOCKABLE MutexLock" slurp "$inc/time/time.h" has abseil-cpp/api-duration "class Duration" has abseil-cpp/api-timezone "class TimeZone" has abseil-cpp/api-time "class Time" slurp "$inc/container/flat_hash_map.h" has abseil-cpp/api-flathash "class flat_hash_map" slurp "$inc/numeric/int128.h" has abseil-cpp/api-int128 "class int128 {" slurp "$inc/types/span.h" has abseil-cpp/api-span "class Span" slurp "$inc/strings/cord.h" has abseil-cpp/api-cord "class Cord" # 4. THE PORT'S PATCHES, in the headers that ship them. Both are guards the stock # source does not have; each is one line of evidence that its patch applied. slurp "$inc/base/internal/direct_mmap.h" has abseil-cpp/patch-mmap-wasm32 "defined(__wasm32__)" has abseil-cpp/patch-mmap-syscall "syscall(SYS_mmap, start, length, prot, flags, fd, offset)" slurp "$inc/synchronization/internal/stdcpp_waiter.h" has abseil-cpp/patch-stdcpp-guard "_LIBCPP_HAS_THREADS" # --------------------------------------------------------------------------- # 5. pkg-config. 185 files, one per absl_cc_library. The count comes off a glob # rather than `ls | wc -l`, which would be two execs for one number. check abseil-cpp/pc-dir test -d "$pc" set -- "$pc"/absl_*.pc check_eq abseil-cpp/pc-count 185 "$#" for c in strings base synchronization time status; do check "abseil-cpp/pc-$c-present" test -s "$pc/absl_$c.pc" slurp "$pc/absl_$c.pc" has "abseil-cpp/pc-$c-name" "Name: absl_$c" has "abseil-cpp/pc-$c-version" "Version: 20240116" has "abseil-cpp/pc-$c-libs" "-labsl_$c" done slurp "$pc/absl_base.pc" has abseil-cpp/pc-libdir "libdir=/usr/lib" # 6. The CMake package -- the interface re2 and protobuf will actually use, since # both find abseil with find_package(absl) rather than pkg-config. for f in abslConfig.cmake abslConfigVersion.cmake abslTargets.cmake abslTargets-noconfig.cmake; do check "abseil-cpp/cmake-${f}" test -s "$cmk/$f" done slurp "$cmk/abslConfigVersion.cmake" has abseil-cpp/cmake-version "20240116" slurp "$cmk/abslTargets.cmake" has abseil-cpp/cmake-target "absl::strings" # Static-only, stated by the import records rather than by the absence of files. slurp "$cmk/abslTargets-noconfig.cmake" if bst_ps_converted "$lib/libabsl_base.so" "$lib/libabsl_base.so.*"; then has abseil-cpp/cmake-imports-static "libabsl_strings.so" case "$SLURP" in *libabsl_strings.a*) bst_notok abseil-cpp/cmake-no-so "abslTargets-noconfig.cmake names an archive on a converted abseil" ;; *) bst_ok abseil-cpp/cmake-no-so ;; esac else has abseil-cpp/cmake-imports-static "libabsl_strings.a" case "$SLURP" in *.so*) bst_notok abseil-cpp/cmake-no-so "abslTargets-noconfig.cmake names a shared object" ;; *) bst_ok abseil-cpp/cmake-no-so ;; esac fi # 7. The archives. 86 of them; nine are read in full below. # The versioned name only: the class also stages digest-named copies of each .so. if [ "$CONVERTED" = 1 ]; then set -- "$lib"/libabsl_*.so.2401.0.0; else set -- "$lib"/libabsl_*.a; fi check_eq abseil-cpp/lib-count 86 "$#" # Shape, not absence: this arm converts to shared libraries per recipe # (BRINTOS-1740), so a .so here is a conversion, not a policy breach. bst_lib_shape abseil-cpp/no-shared "$lib/libabsl_*.so*" set -- "$lib"/libabsl_*.la if [ -e "$1" ]; then bst_notok abseil-cpp/no-libtool "$1 exists"; else bst_ok abseil-cpp/no-libtool; fi tmp=${TMPDIR:-/tmp} pat=$tmp/bst-abseil-pat.$$ hit=$tmp/bst-abseil-hit.$$ # absl_scan ... : the two execs this suite spends per archive. # # `tr` first because GNU grep suppresses matches inside data it classifies as # binary and busybox tr does not handle [:print:] under -c, so this octal range # is the formulation both greps and both trs agree on -- and the members here are # LLVM bitcode, whose string table it still exposes. Then ONE grep for every # needle at once, into a small file the shell reads with no further exec. # # TWO DETAILS THAT LOOK LIKE STYLE AND ARE NOT, both measured against busybox: # # * the map is to NEWLINE, not to space. An archive flattened with spaces is # essentially ONE line, and busybox grep's -o reports only the first match # per line where GNU grep reports every non-overlapping one. Under `busybox # ash` -- which runs applets directly, bypassing PATH, so it is busybox grep # whatever the image also installs -- that silently cost 15 of 34 matches on # libabsl_strings.a alone, and every case it cost went red for a symbol that # is present. Splitting on newline makes the file 819,878 short lines. # * `grep -F -f`, NOT `grep -o -F -f`. Keeping whole matching lines takes -o # out of the picture entirely, and the two greps then agree exactly: 28 # lines / 57,530 bytes for the strings scan, from both. # # AND ONE THAT IS A PLATFORM DEFECT, NOT A CHOICE: the tr stays in a PIPELINE. # # BRINTOS-WORKAROUND: brintos/linux#73 remove -- `tr < ` # written as a plain top-level command makes dup2(2) return the kernel's restart # park sentinel 513; ash treats the failed redirect as fatal and exits, so the # suite ends mid-run and the runner reports every case that did emit as a pass. # This suite lost 99 of its 189 cases to exactly that and still printed a clean # ==BST-END==. A pipeline is safe because the shell forks before performing the # redirect -- see the README's "Do not redirect stdin from the rootfs", which # carries the 20/20-vs-0/20 measurement. Do not "tidy" this into `tr < a > f`. absl_scan() { _c=$1; shift _f=$(bst_ps_lib "$lib/libabsl_$_c.a" "$lib/libabsl_$_c.so.2401.0.0") check "abseil-cpp/ar-$_c-present" test -s "$_f" if [ "$CONVERTED" = 1 ]; then _magic=$(od -An -tx1 -N 4 "$_f" 2>/dev/null | tr -d ' \n') case "$_magic" in 0061736d) bst_ok "abseil-cpp/ar-$_c-magic" ;; *) bst_notok "abseil-cpp/ar-$_c-magic" "not a wasm module (magic $_magic)" ;; esac else # The archive magic, read with the `read` builtin rather than `head -c 8`, # and fed by a PIPELINE rather than by a redirect any shell here performs. # BRINTOS-WORKAROUND: brintos/linux#73 remove -- dup2 on the virtiofs root # returns 513 and kills the shell that called it. # The substitution alone was NOT enough, though the comment here used to say # it was: the fork moves the dup2 into the subshell, which then dies at the # redirect, so the printf after it never ran and _magic came back empty -- # every ar-*-magic case taking its not-ok branch on a correct archive. The # fork only ever saved the redirecting command (BRINTOS-1566). cat opens the # file itself, so no shell redirects from the rootfs at all. _magic=$(cat "$lib/libabsl_$_c.a" 2>/dev/null | { IFS= read -r _m; printf '%s' "$_m"; }) case "$_magic" in "!"*) bst_ok "abseil-cpp/ar-$_c-magic" ;; *) bst_notok "abseil-cpp/ar-$_c-magic" "first line is not !" ;; esac fi : > "$pat" for _n in "$@"; do printf '%s\n' "$_n" >> "$pat"; done tr -c '\40-\176' '\n' < "$_f" 2>/dev/null | grep -F -f "$pat" > "$hit" 2>/dev/null slurp "$hit" } # member : an archive member name; a shared object has none. member() { if [ "$CONVERTED" = 1 ]; then bst_skip "$1" "libabsl_*.so shipped; a converted abseil builds no archive members" else has "$1" "$2" fi } # 7a. strings -- the largest component, 14 translation units. absl_scan strings \ ascii.cc.o charconv.cc.o escaping.cc.o match.cc.o numbers.cc.o \ str_cat.cc.o str_replace.cc.o str_split.cc.o substitute.cc.o \ _ZN4absl12lts_2024011610CHexEscapeENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE \ _ZN4absl12lts_2024011610SimpleAtobENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEEPb \ _ZN4absl12lts_2024011610SimpleAtodENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEEPd \ _ZN4absl12lts_2024011612Base64EscapeENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE \ _ZN4absl12lts_2024011613StrReplaceAllENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE \ _ZN4absl12lts_2024011610from_charsEPKcS2_RdNS0_12chars_formatE for m in ascii charconv escaping match numbers str_cat str_replace str_split substitute; do member "abseil-cpp/strings-member-$m" "$m.cc.o" done has abseil-cpp/strings-sym-chexescape "10CHexEscapeENSt3__117basic_string_view" has abseil-cpp/strings-sym-simpleatob "10SimpleAtobENSt3__117basic_string_view" has abseil-cpp/strings-sym-simpleatod "10SimpleAtodENSt3__117basic_string_view" has abseil-cpp/strings-sym-base64 "12Base64EscapeENSt3__117basic_string_view" has abseil-cpp/strings-sym-strreplace "13StrReplaceAllENSt3__117basic_string_view" has abseil-cpp/strings-sym-fromchars "10from_charsEPKcS2_RdNS0_12chars_formatE" # 7b. base -- five translation units, and the one this port had to patch. # NumCPUs is patch 0006's function: upstream reads # std::thread::hardware_concurrency(), which does not exist on a libc++ built # LIBCXX_ENABLE_THREADS=OFF. Its presence here is the whole reason absl/base # compiles at all on this arm. absl_scan base \ cycleclock.cc.o spinlock.cc.o sysinfo.cc.o thread_identity.cc.o \ _ZN4absl12lts_2024011613base_internal7NumCPUsEv \ _ZN4absl12lts_2024011613base_internal6GetTIDEv \ _ZN4absl12lts_2024011613base_internal19NominalCPUFrequencyEv \ _ZN4absl12lts_2024011613base_internal10CycleClock3NowEv \ _ZN4absl12lts_2024011613base_internal8SpinLock8SlowLockEv \ _ZN4absl12lts_2024011613base_internal30CurrentThreadIdentityIfPresentEv for m in cycleclock spinlock sysinfo thread_identity; do member "abseil-cpp/base-member-$m" "$m.cc.o" done has abseil-cpp/base-sym-numcpus "base_internal7NumCPUsEv" has abseil-cpp/base-sym-gettid "base_internal6GetTIDEv" has abseil-cpp/base-sym-cpufreq "base_internal19NominalCPUFrequencyEv" has abseil-cpp/base-sym-cycleclock "base_internal10CycleClock3NowEv" has abseil-cpp/base-sym-spinlock "base_internal8SpinLock8SlowLockEv" has abseil-cpp/base-sym-threadid "base_internal30CurrentThreadIdentityIfPresentEv" # 7c. synchronization -- and the waiter question, which is this port's. # FutexWaiter is the waiter this arm selects; StdcppWaiter is the one patch # 0008 compiles away, because it needs a std::mutex the standard library here # does not declare. Both halves are asserted: a StdcppWaiter symbol appearing # would mean the guard stopped applying, and a missing FutexWaiter would mean # the selection moved -- and either would be silent in the build log. absl_scan synchronization \ mutex.cc.o notification.cc.o barrier.cc.o blocking_counter.cc.o \ futex_waiter.cc.o waiter_base.cc.o per_thread_sem.cc.o \ _ZN4absl12lts_202401165Mutex10ReaderLockEv \ _ZN4absl12lts_202401165Mutex12ReaderUnlockEv \ _ZN4absl12lts_202401165Mutex11TryLockSlowEv \ _ZN4absl12lts_202401165Mutex18ForgetDeadlockInfoEv \ _ZN4absl12lts_2024011612Notification6NotifyEv \ _ZN4absl12lts_2024011615BlockingCounter4WaitEv \ _ZN4absl12lts_2024011624synchronization_internal11FutexWaiter4WaitENS1_13KernelTimeoutE \ _ZN4absl12lts_2024011624synchronization_internal11FutexWaiter4PostEv \ _ZN4absl12lts_2024011624synchronization_internal11FutexWaiter4PokeEv \ synchronization_internal12StdcppWaiter \ AbslInternalMutexYield_lts_20240116 for m in mutex notification barrier blocking_counter futex_waiter waiter_base per_thread_sem; do member "abseil-cpp/sync-member-$m" "$m.cc.o" done has abseil-cpp/sync-sym-readerlock "5Mutex10ReaderLockEv" has abseil-cpp/sync-sym-readerunlock "5Mutex12ReaderUnlockEv" has abseil-cpp/sync-sym-trylockslow "5Mutex11TryLockSlowEv" has abseil-cpp/sync-sym-forgetdl "5Mutex18ForgetDeadlockInfoEv" has abseil-cpp/sync-sym-notify "12Notification6NotifyEv" has abseil-cpp/sync-sym-blockcounter "15BlockingCounter4WaitEv" has abseil-cpp/sync-futex-wait "11FutexWaiter4WaitENS1_13KernelTimeoutE" has abseil-cpp/sync-futex-post "11FutexWaiter4PostEv" has abseil-cpp/sync-futex-poke "11FutexWaiter4PokeEv" has abseil-cpp/sync-yield-hook "AbslInternalMutexYield_lts_20240116" case "$SLURP" in *synchronization_internal12StdcppWaiter*) bst_notok abseil-cpp/sync-no-stdcpp-waiter "a StdcppWaiter symbol is present: patch 0008's guard stopped applying" ;; *) bst_ok abseil-cpp/sync-no-stdcpp-waiter ;; esac # 7d. time. absl_scan time \ civil_time.cc.o clock.cc.o duration.cc.o format.cc.o time.cc.o \ _ZN4absl12lts_202401163NowEv \ _ZN4absl12lts_2024011619GetCurrentTimeNanosEv \ _ZN4absl12lts_2024011614FormatDurationENS0_8DurationE \ _ZN4absl12lts_2024011610FormatTimeENS0_4TimeENS0_8TimeZoneE \ _ZN4absl12lts_2024011611ToUnixNanosENS0_4TimeE \ _ZN4absl12lts_2024011610ToTimespecENS0_8DurationE for m in civil_time clock duration format time; do member "abseil-cpp/time-member-$m" "$m.cc.o" done has abseil-cpp/time-sym-now "12lts_202401163NowEv" has abseil-cpp/time-sym-nowns "19GetCurrentTimeNanosEv" has abseil-cpp/time-sym-fmtduration "14FormatDurationENS0_8DurationE" has abseil-cpp/time-sym-fmttime "10FormatTimeENS0_4TimeENS0_8TimeZoneE" has abseil-cpp/time-sym-unixnanos "11ToUnixNanosENS0_4TimeE" has abseil-cpp/time-sym-timespec "10ToTimespecENS0_8DurationE" # 7e. status. absl_scan status \ status.cc.o status_internal.cc.o status_payload_printer.cc.o \ _ZN4absl12lts_202401166StatusC1ENS0_10StatusCodeENSt3__117basic_string_viewIcNS3_11char_traitsIcEEEE \ _ZN4absl12lts_202401166Status11EmptyStringEv \ _ZN4absl12lts_202401166Status12ToStringSlowEmNS0_18StatusToStringModeE \ _ZN4absl12lts_2024011610IsNotFoundERKNS0_6StatusE \ _ZN4absl12lts_2024011611IsCancelledERKNS0_6StatusE \ _ZN4absl12lts_2024011613InternalErrorENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE for m in status status_internal status_payload_printer; do member "abseil-cpp/status-member-$m" "$m.cc.o" done has abseil-cpp/status-sym-ctor "6StatusC1ENS0_10StatusCodeENSt3__117basic_string_view" has abseil-cpp/status-sym-emptystring "6Status11EmptyStringEv" has abseil-cpp/status-sym-tostring "6Status12ToStringSlowEmNS0_18StatusToStringModeE" has abseil-cpp/status-sym-isnotfound "10IsNotFoundERKNS0_6StatusE" has abseil-cpp/status-sym-iscancelled "11IsCancelledERKNS0_6StatusE" has abseil-cpp/status-sym-internalerr "13InternalErrorENSt3__117basic_string_view" # --------------------------------------------------------------------------- # 8. Vtables, typeinfo and typeinfo-names. THIS is the block that says the C++ # arm of the toolchain genuinely worked: there is no way for the C driver # every other library in this image is built with to emit a _ZTV/_ZTI/_ZTS # record. Two of the types below -- BadStatusOrAccess and SeedGenException -- # derive from std::exception, so their RTTI exists here under -fno-exceptions, # which is the arm this whole C++ round is on. absl_scan log_sink \ _ZTVN4absl12lts_202401167LogSinkE _ZTIN4absl12lts_202401167LogSinkE \ _ZTSN4absl12lts_202401167LogSinkE has abseil-cpp/rtti-logsink-vtable "_ZTVN4absl12lts_202401167LogSinkE" has abseil-cpp/rtti-logsink-typeinfo "_ZTIN4absl12lts_202401167LogSinkE" has abseil-cpp/rtti-logsink-typename "_ZTSN4absl12lts_202401167LogSinkE" absl_scan statusor \ _ZTVN4absl12lts_2024011617BadStatusOrAccessE _ZTIN4absl12lts_2024011617BadStatusOrAccessE \ _ZTSN4absl12lts_2024011617BadStatusOrAccessE \ _ZN4absl12lts_2024011617BadStatusOrAccessC1ENS0_6StatusE has abseil-cpp/rtti-badstatusor-vtable "_ZTVN4absl12lts_2024011617BadStatusOrAccessE" has abseil-cpp/rtti-badstatusor-typeinfo "_ZTIN4absl12lts_2024011617BadStatusOrAccessE" has abseil-cpp/rtti-badstatusor-typename "_ZTSN4absl12lts_2024011617BadStatusOrAccessE" has abseil-cpp/rtti-badstatusor-ctor "17BadStatusOrAccessC1ENS0_6StatusE" absl_scan random_seed_gen_exception \ _ZTVN4absl12lts_2024011616SeedGenExceptionE _ZTIN4absl12lts_2024011616SeedGenExceptionE \ _ZTSN4absl12lts_2024011616SeedGenExceptionE has abseil-cpp/rtti-seedgen-vtable "_ZTVN4absl12lts_2024011616SeedGenExceptionE" has abseil-cpp/rtti-seedgen-typeinfo "_ZTIN4absl12lts_2024011616SeedGenExceptionE" has abseil-cpp/rtti-seedgen-typename "_ZTSN4absl12lts_2024011616SeedGenExceptionE" # cctz's time-zone hierarchy: an abstract TimeZoneIf with two implementations, # plus the ZoneInfoSource loader. time_zone_impl.cc.o is patch 0009's file -- the # time-zone cache lock, which needed a std::mutex that is not declared here. absl_scan time_zone \ time_zone_impl.cc.o time_zone_info.cc.o time_zone_libc.cc.o \ time_zone_lookup.cc.o zone_info_source.cc.o \ _ZTVN4absl12lts_2024011613time_internal4cctz10TimeZoneIfE \ _ZTVN4absl12lts_2024011613time_internal4cctz12TimeZoneInfoE \ _ZTVN4absl12lts_2024011613time_internal4cctz12TimeZoneLibCE \ _ZTVN4absl12lts_2024011613time_internal4cctz14ZoneInfoSourceE \ _ZN4absl12lts_2024011613time_internal4cctz9time_zone4Impl12LoadTimeZoneE for m in time_zone_impl time_zone_info time_zone_libc time_zone_lookup zone_info_source; do member "abseil-cpp/tz-member-$m" "$m.cc.o" done has abseil-cpp/rtti-cctz-timezoneif "cctz10TimeZoneIfE" has abseil-cpp/rtti-cctz-timezoneinfo "cctz12TimeZoneInfoE" has abseil-cpp/rtti-cctz-timezonelibc "cctz12TimeZoneLibCE" has abseil-cpp/rtti-cctz-zoneinfosrc "cctz14ZoneInfoSourceE" has abseil-cpp/tz-sym-loadtimezone "9time_zone4Impl12LoadTimeZoneE" rm -f "$pat" "$hit"