Skip to content

Give externally-provided symbol declarations default visibility - #2136

Open
rvandermeulen wants to merge 1 commit into
abseil:masterfrom
rvandermeulen:sanitizer-and-mmap2-visibility
Open

Give externally-provided symbol declarations default visibility#2136
rvandermeulen wants to merge 1 commit into
abseil:masterfrom
rvandermeulen:sanitizer-and-mmap2-visibility

Conversation

@rvandermeulen

Copy link
Copy Markdown
Contributor

Abseil forward-declares a few symbols that are provided by something outside the object being linked:

Symbol(s) File Provided by
14x Annotate* race annotations absl/base/dynamic_annotations.h sanitizer runtime
__tsan_read1 absl/synchronization/mutex.cc sanitizer runtime
__mmap2 absl/base/internal/direct_mmap.h Bionic

None of these has a public header to include — none of the Annotate* functions nor __tsan_read1 appears in any compiler-rt sanitizer/*.h, and __mmap2 is a private Bionic symbol — so declaring them locally is the only option. But a local declaration inherits whatever visibility is in effect at that point.

When the translation unit is compiled with -fvisibility=hidden and abseil is linked into a shared library, those references become hidden undefined symbols. They then cannot be resolved from the sanitizer runtime (which lives in the executable) or from libc, and the link fails:

ld.lld: error: undefined hidden symbol: AnnotateIgnoreReadsBegin
ld.lld: error: undefined hidden symbol: AnnotateIgnoreWritesBegin
ld.lld: error: undefined hidden symbol: AnnotateIgnoreWritesEnd
ld.lld: error: undefined hidden symbol: AnnotateIgnoreReadsEnd
ld.lld: error: undefined hidden symbol: __tsan_read1
ld.lld: error: undefined hidden symbol: __mmap2

This wraps each declaration in #pragma GCC visibility push(default) / pop.

Verification

Compiling all ~163 abseil sources with -fsanitize=thread and a tree-wide #pragma GCC visibility push(hidden), then scanning every object for hidden undefined symbols: before this change the four Annotate* and __tsan_read1 are GLOBAL HIDDEN UND; after, every __tsan_* and Annotate* reference is GLOBAL DEFAULT UND. The only hidden undefined symbols remaining are AbslInternal* ones that abseil defines itself, which is correct.

For __mmap2, on a 32-bit Android shared-library link:

without the pragma:  ld.lld: error: undefined hidden symbol: __mmap2
with the pragma:     4: FUNC GLOBAL DEFAULT UND __mmap2@LIBC

Notes

  • Every affected site is already inside a Bionic or sanitizer guard, so the GCC/Clang-only pragma does not reduce portability.
  • The __mmap2 path only compiles on 32-bit architectures, which is why this is rarely hit — Chromium's Android builds are 64-bit. We hit it on 32-bit ARM.
  • Found while updating the copy of abseil vendored into Firefox, which builds with -fvisibility=hidden tree-wide.

Abseil forward-declares a handful of symbols that are provided by something
outside the object being linked: the compiler-based sanitizer runtime supplies
the Annotate* race annotations and __tsan_read1, and Bionic supplies __mmap2.
None of these have a public header to include, so declaring them locally is the
only option, but the declarations inherit whatever visibility is in effect.

When a translation unit is compiled with -fvisibility=hidden and abseil is
linked into a shared library, those references become hidden undefined symbols
and cannot be resolved from the runtime or from libc, so the link fails:

  ld.lld: error: undefined hidden symbol: AnnotateIgnoreReadsBegin
  ld.lld: error: undefined hidden symbol: AnnotateIgnoreWritesBegin
  ld.lld: error: undefined hidden symbol: __tsan_read1
  ld.lld: error: undefined hidden symbol: __mmap2

Wrap the declarations in a visibility push/pop so they stay resolvable. Every
site is already inside a Bionic or sanitizer guard, so this does not affect
platforms where the attribute is unavailable.
@rvandermeulen
rvandermeulen force-pushed the sanitizer-and-mmap2-visibility branch from 7c3e130 to ab78d3a Compare August 22, 2026 22:08
@derekmauro derekmauro self-assigned this Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants