diff options
Diffstat (limited to 'nx-X11/config/util/elistgen.sun')
-rw-r--r-- | nx-X11/config/util/elistgen.sun | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/nx-X11/config/util/elistgen.sun b/nx-X11/config/util/elistgen.sun new file mode 100644 index 000000000..f9af50ad1 --- /dev/null +++ b/nx-X11/config/util/elistgen.sun @@ -0,0 +1,267 @@ +XCOMM!/bin/sh -f +XCOMM $Xorg: elistgen.sun,v 1.3 2000/08/17 19:41:52 cpqbld Exp $ +XCOMM +XCOMM ######################################################################## +XCOMM Construct shared-library scoping mapfile for Solaris based on standardized +XCOMM export list description file +XCOMM +XCOMM Usage: exportlistgen libfoo.so libfoo.elist > mapfile.scope +XCOMM +XCOMM libfoo.so => shared library of interest +XCOMM libfoo.elist => Meta description of necessary export list. +XCOMM +XCOMM The output file, "mapfile.scope" may then be passed to the Solaris +XCOMM linker to reconstruct the shared library, libfoo.so. +XCOMM +XCOMM ######################################################################## +XCOMM +XCOMM $XFree86: xc/config/util/elistgen.sun,v 1.7 2001/01/17 16:39:01 dawes Exp $ + +XCOMM Utility programs +FILTER=CXXFILT # C++ symbol demangler +AWK=nawk # Awk + +XCOMM For nm, cat, pr, sed, awk, c++filt +PATH=/usr/bin:/bin:/usr/ccs/bin:/usr/ucb:$PATH + +XCOMM Try to detect broken versions of c++filt. +if [ `echo _okay | ${FILTER:-cat}` != "_okay" ]; then + if [ -x /opt/SUNWspro/bin/c++filt ]; then + echo "# Your $FILTER is broken -- using /opt/SUNWspro/bin/c++filt." + FILTER=/opt/SUNWspro/bin/c++filt + else + echo "# ERROR: no working $FILTER available." + exit 1 + fi; +fi; + +XCOMM Temporary files +EXPORTLIST=/tmp/elistgen1.$$ # export directives from "libfoo.list" +NMLIST=/tmp/elistgen2.$$ # name list from libfoo.sl +FILTLIST=/tmp/elistgen3.$$ # demangled (C++) version of above + +XCOMM Print useful information at the top of the output +echo "#" `date` +echo "# This scoping mapfile was produced by" $0 +echo "# Export list description taken from:" $2 +echo "# Target library:" $1 +echo "# Target Operating System:" `uname -msrv` +echo "# " + +XCOMM Extract the globally visible symbols from target library +XCOMM The NMLIST generated here is later used to cross-check the symbols in the +XCOMM nm stopped working on Solaris 2.5, use dump instead. +nm -p $1 | $AWK '/ [ TDBS] /{print $3}' > $NMLIST +XCOMM /usr/ccs/bin/dump -t -v $1 | $AWK '/(FUNC|OBJT).(GLOB|WEAK)/{print $8}' > $NMLIST + +XCOMM Extract the globally visible symbols from target library +XCOMM The NMLIST generated here is later used to cross-check the symbols in the +${FILTER:-cat} < $NMLIST > $FILTLIST + +XCOMM Clean up the export-list description file. Sort the directives. +$AWK ' + BEGIN { + csyms = 0; # C public symbols in libfoo.list + cplusplus = 0; # C++ public symbols in libfoo.list + isyms = 0; # C internal symbols in libfoo.list + iplusplus = 0; # C++ internal symbols in libfoo.list + implicit = ""; # Handling of implicit symbols + } + $1 == "default" { + # A default clause suppresses warnings about implicit symbols. + if ($2 != "" && $2 != "force" && $2 != "public" && $2 != "private" && $2 != "internal") { + print "# Warning: illegal default clause:", $2 | "cat 1>&2"; + next; + } + if (implicit != "") + print "# Warning: multiple default clauses." | "cat 1>&2"; + implicit = $2; + next; + } + $1 == "force" { + csyms ++; + print $1 ";;" $2; + next; + } + $1 == "public" { + csyms ++; + print $1 ";;" $2; + next; + } + $1 == "publicC++" { + cplusplus ++; + string = $2; + for (n = 3; n <= NF; n++) + string = string " " $n; + print $1 ";;" string; + next; + } + $1 == "private" { + csyms ++; + print $1 ";;" $2; + next; + } + $1 == "privateC++" { + cplusplus ++; + string = $2; + for (n = 3; n <= NF; n++) + string = string " " $n; + print $1 ";;" string; + next; + } + $1 == "internal" { + isyms ++; + print $1 ";;" $2; + next; + } + $1 == "internalC++" { + iplusplus ++; + string = $2; + for (n = 3; n <= NF; n++) + string = string " " $n; + print $1 ";;" string; + next; + } + $1 == "#line" || $1 == "#" { + # cpp will have removed comments, but may have added other stuff. + next; + } + NF > 0 { + print "# Warning: unrecognized directive:", $0 | "cat 1>&2"; + next; + } + END { + printf("# Exporting %d C and %d C++ symbols, hiding %d and %d.\n", csyms, cplusplus, isyms, iplusplus) | "cat 1>&2"; + if (implicit != "") { + print "# Unspecified symbols are " implicit "." | "cat 1>&2"; + print "default;;" implicit; + } + } +' $2 1>$EXPORTLIST + + +XCOMM Read in the above files and write result to stdout. The contents +XCOMM of NMLIST and FILTLIST are used to construct a symbol lookup table. +XCOMM The contents of EXPORTLIST are converted with the help of this table. +XCOMM Use ";" as a delimiter in the symbol lookup table. +(pr -m -s";" -t -w1024 $NMLIST $FILTLIST | sed 's/ / /g'; cat $EXPORTLIST) | $AWK ' + BEGIN { + FS = ";"; + implicit = 0; + } + NF == 2 { + # This is "pr" output, i.e., symbol translation table + r2=$2; + gsub(/static /,"",r2); # remove keyword "static" as above + gsub(/ /,"",r2); # Remove spaces because c++filt is unpredictable + syms[r2] = $1; + r1=$1; + gsub(/ /,"",r1); + mangled[r1] = 1; # Save the mangling because the export lists + # sometimes use it instead of a prototype. + next; + } + NF == 3 && $1 == "default" { + # Treatment of unspecified symbols. + if ($3 == "internal" || $3 == "internalC++") + implicit = 1; + else if ($3 == "private" || $3 == "privateC++") + implicit = 2; + else if ($3 == "public" || $3 == "publicC++") + implicit = 3; + else # $3 == "force" + implicit = 4; + next; + } + NF == 3 { + # Generate canonical demangled form as an alternate symbol. + alt=$3; + gsub(/ \.\.\./,",...",alt); # change " ..." to ",..." to match c++filt + gsub(/ /,"",alt); # remove all spaces + + # An export directive. Parse our instructions for this symbol. + if ($1 == "internal" || $1 == "internalC++") + export = 1; + else if ($3 == "private" || $3 == "privateC++") + export = 2; + else if ($3 == "public" || $3 == "publicC++") + export = 3; + else # $3 == "force" + export = 4; + + # Process it. + if ((length(syms[alt]) > 0) || mangled[alt]) { + # This symbol is present in the library. + if (donelist[alt]) + print "# Warning: Duplicate entry for", $3, + "in export list" | "cat 1>&2"; + if (donelist[alt] < export) { + donelist[alt] = export; + } + } else { + # Print forced-export symbols without complaining. + if (export == 4) { + donelist[alt] = export; + } else { + print "# Warning:", $3, + "was not in the nm list for this library" | "cat 1>&2"; + } + } + + next; + } + END { + # Ignore magic linker symbols. + if (implicit == 0) { + if (!donelist["_DYNAMIC"]) + donelist["_DYNAMIC"] = 1; + if (!donelist["_GLOBAL_OFFSET_TABLE_"]) + donelist["_GLOBAL_OFFSET_TABLE_"] = 1; + if (!donelist["_PROCEDURE_LINKAGE_TABLE_"]) + donelist["_PROCEDURE_LINKAGE_TABLE_"] = 1; + if (!donelist["_edata"]) + donelist["_edata"] = 1; + if (!donelist["_end"]) + donelist["_end"] = 1; + if (!donelist["_etext"]) + donelist["_etext"] = 1; + } + + # Process implicit symbols. + for (i in syms) { + if (donelist[i] == 0 && length(syms[i]) > 0) { + if (implicit == 0) { + # Ignore magic symbols introduced by the C++ compiler. + if ((syms[i] !~ /^__vtbl__[0-9]*_/) && (syms[i] !~ /^__ptbl_vec__/)) + print "# Warning:", syms[i], "was not in the export list" | "cat 1>&2"; + } else { + donelist[i] = implicit; + } + } + } + + # Generate the linker file. + print ""; + print "SUNW.1.1 {"; + print " global:"; + for (i in syms) + if (donelist[i] >= 2 && length(syms[i]) > 0) + print " " syms[i] ";"; + print " local:"; + print " *;"; + print "};"; + + print ""; + print "SUNW_private.1.1 {"; + print " global:"; + for (i in syms) + if (donelist[i] == 1 && length(syms[i]) > 0) + print " " syms[i] ";"; + print "} SUNW.1.1;" + } +' + +XCOMM Clean up temporary files +rm $EXPORTLIST +rm $NMLIST +rm $FILTLIST |