Skip to content

Resolve undefined symbols across the executable's global scope#1

Merged
mariotaku merged 2 commits into
mainfrom
claude/libegl-symbol-false-positive-frf6ep
Jun 26, 2026
Merged

Resolve undefined symbols across the executable's global scope#1
mariotaku merged 2 commits into
mainfrom
claude/libegl-symbol-false-positive-frf6ep

Conversation

@mariotaku

Copy link
Copy Markdown
Member

Problem

ipk-verify flags hundreds of false "undefined symbol" errors for libraries whose imports are actually provided by a sibling library the executable also loads.

This surfaced on apps-repo PR #190 (org.webosbrew.bridge-64to32): the compat check reports required lib libEGL.so.1 as :x: on every firmware, with ~275 gl* symbols (glActiveTexture, glBindBuffer, …) listed as undefined — while libGLESv2.so.2 passes.

Root cause

Analysing the bundled binaries:

  • The bridge's libEGL.so.1 is a thin EGL shim with 275 undefined gl* imports and a DT_NEEDED of only libgles_bridge_core.so + libc.so.6 — it does not list libGLESv2.so.2.
  • Those gl* functions are defined by the sibling bundled libGLESv2.so.2.
  • The app executable DT_NEEDEDs both libs (with RPATH=$ORIGIN/lib), so at runtime the loader places both into one global symbol scope and libEGL's gl* references bind to libGLESv2. It works.

But verify checked each bundled library in isolation: it only struck off symbols reachable through that library's own DT_NEEDED chain (recursive_resolve_symbols follows lib.needed). Since libEGL doesn't directly depend on libGLESv2, the gl* imports were never resolved → false "undefined" reports. The stock firmware libEGL.so.1 only ever exported egl*, so matching against firmware failed too.

Fix

After resolving each bundled library against its own DT_NEEDED chain, also resolve any remaining undefined symbols against the executable's global scope — the dependency closure rooted at the executable's DT_NEEDED — mirroring the real dynamic loader (common/verify/src/ipk/component.rs). Genuinely missing libraries and symbols are still reported.

Verification

Ran the rebuilt webosbrew-ipk-verify against the real org.webosbrew.bridge-64to32 IPK across all 13 firmware datasets:

Row Before After
required lib libEGL.so.1 ❌ ×13
required lib libwayland-egl.so.1
required lib libpulse.so.0 / libpulse-simple.so.0 ❌ (genuine — bundled libpulsecommon-15.0.so is in a lib/pulse-15.0/ subdir that isn't on the search path)

The fix is surgical: it clears the sibling-scope false positives while leaving real missing-library/missing-symbol problems intact.

Added regression tests in packages/ipk-verify/tests/global_scope.rs (sibling-provided symbol passes; truly-missing symbol still fails). Existing tests unaffected.

Bumps verify-lib 0.1.2 → 0.1.3 and ipk-verify 0.1.4 → 0.1.5.

🤖 Generated with Claude Code


Generated by Claude Code

Claude and others added 2 commits June 26, 2026 04:54
elf-verify checked each bundled library's undefined symbols only against
that library's own DT_NEEDED chain. At runtime the dynamic loader instead
resolves every loaded object against a single global scope made up of the
executable and its whole dependency closure, so a library's imports can be
satisfied by a sibling library the executable also loads without any direct
DT_NEEDED link between them.

This produced false "undefined symbol" reports for libraries that import
from a sibling — e.g. a libEGL.so.1 shim whose gl* imports are provided by
the sibling libGLESv2.so.2 (apps-repo PR #190 flagged ~275 gl* symbols as
undefined on every firmware).

After resolving each bundled library against its own DT_NEEDED chain, also
resolve any remaining undefined symbols against the executable's global
scope. Genuinely missing libraries and symbols are still reported.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011jY7WzoWeU9TWRBhWJ2Wbq
The global-scope symbol resolution fix changes ipk-verify's output
(libraries whose imports are satisfied by a sibling no longer report
false undefined-symbol errors). Bump the affected crates so the new
behaviour ships as a distinct release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011jY7WzoWeU9TWRBhWJ2Wbq
@mariotaku mariotaku merged commit cd038b0 into main Jun 26, 2026
1 check passed
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.

1 participant