@ 261105.16
current
#!/bin/sh
# Writes out all of the exported symbols to a file.
# This is needed on AIX as symbols are not exported
# by an executable by default and need to be listed
# specifically for export so that they can be used
# by native add-ons.
#
# The raw symbol data is obtained by using dump -tov on
# the .a files which make up the node executable.
#
# dump -tov flags:
# -t: Display symbol table entries
# -o: Display object file headers
# -v: Display visibility information (HIDDEN/EXPORTED/PROTECTED)
# -X 32_64: Process both 32-bit and 64-bit symbols
#
# This approach is similar to CMake's ExportImportList module for AIX:
# https://github.com/Kitware/CMake/blob/45f4742cbfe6c25c7c801e3806c8af04a2c4b09b/Modules/Platform/AIX/ExportImportList#L67-L80
#
# We filter for symbols in .text, .data, .tdata, and .bss sections
# with extern or weak linkage, excluding:
# - Symbols starting with dot (internal/local symbols)
# - __sinit/__sterm (static initialization/termination)
# - __[0-9]+__ (compiler-generated symbols)
# - HIDDEN visibility symbols (to avoid linker error 0711-407)
#
# The final sort allows removal of any duplicates.
#
# Symbols for the gtest libraries are excluded as
# they are not linked into the node executable.
#
echo "Searching $1 to write out expfile to $2"

# This special sequence must be at the start of the exp file.
echo "#!." > "$2.tmp"

# Pull the symbols from the .a files.
# Use dump -tov to get visibility information and exclude HIDDEN symbols.
# This prevents AIX linker error 0711-407 when addons try to import symbols
# with visibility attributes.
#
# IMPORTANT: AIX dump -tov output has a visibility column that contains either
# a visibility keyword (HIDDEN/EXPORTED/PROTECTED) or blank spaces when no
# visibility attribute is set. Since AWK splits fields on whitespace, this
# results in different field counts:
#
# With visibility keyword (8 fields after AWK splits):
#   [137] m 0x00003290 .text 1 weak HIDDEN ._ZNKSt3__1...
#    $1  $2    $3      $4   $5  $6    $7        $8
#                              |     |         └─ Symbol name
#                              |     └─ Visibility (HIDDEN/EXPORTED/PROTECTED)
#                              └─ Linkage (weak/extern)
#
# Without visibility keyword (7 fields after AWK splits, spaces collapsed):
#   [77] m 0x00000000 .text 1 weak ._ZN8simdjson...
#    $1 $2    $3      $4   $5  $6       $7
#                             |         └─ Symbol name
#                             └─ Linkage (weak/extern)
#
# The awk script handles both cases by using an associative array V[]
# to map field values to their export suffixes. For fields that don't match
# any key in V[], the lookup returns an empty string, which is perfect for
# handling the variable field positions caused by the blank visibility column.
#
find "$1" -name "*.a" | grep -v gtest | while read -r f; do
    dump -tov -X 32_64 "$f" 2>/dev/null | \
    awk '
        BEGIN {
            V["EXPORTED"]=" export"
            V["PROTECTED"]=" protected"
            V["HIDDEN"]=" hidden"
            V["weak"]=" weak"
        }
        /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|tdata|bss) +[^ ]+ +(extern|weak)( +(EXPORTED|PROTECTED|HIDDEN))?/ {
            # Exclude symbols starting with dot, __sinit, __sterm, __[0-9]+__
            # Also exclude HIDDEN symbols to avoid visibility attribute issues
            if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) {
                # Skip if HIDDEN visibility (can be at $(NF-1) or $(NF-2))
                if ($(NF-1) != "HIDDEN" && $(NF-2) != "HIDDEN") {
                    print $NF V[$(NF-1)] V[$(NF-2)]
                }
            }
        }
    '
done | sort -u >> "$2.tmp"

mv -f "$2.tmp" "$2"