190075Sobrien# Generate an ELF symbol version map a-la Solaris and GNU ld. 290075Sobrien# Contributed by Richard Henderson <rth@cygnus.com> 390075Sobrien# 490075Sobrien# This file is part of GCC. 590075Sobrien# 690075Sobrien# GCC is free software; you can redistribute it and/or modify it under 790075Sobrien# the terms of the GNU General Public License as published by the Free 890075Sobrien# Software Foundation; either version 2, or (at your option) any later 990075Sobrien# version. 1090075Sobrien# 1190075Sobrien# GCC is distributed in the hope that it will be useful, but WITHOUT 1290075Sobrien# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1390075Sobrien# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 1490075Sobrien# License for more details. 1590075Sobrien# 1690075Sobrien# You should have received a copy of the GNU General Public License 1790075Sobrien# along with GCC; see the file COPYING. If not, write to the Free 18169689Skan# Software Foundation, 51 Franklin Street, Fifth Floor, Boston MA 19169689Skan# 02110-1301, USA. 2090075Sobrien 2190075SobrienBEGIN { 2290075Sobrien state = "nm"; 23117395Skan sawsymbol = 0; 24169689Skan if (leading_underscore) 25169689Skan prefix = "_"; 26169689Skan else 27169689Skan prefix = ""; 2890075Sobrien} 2990075Sobrien 3090075Sobrien# Remove comment and blank lines. 3190075Sobrien/^ *#/ || /^ *$/ { 3290075Sobrien next; 3390075Sobrien} 3490075Sobrien 3590075Sobrien# We begin with nm input. Collect the set of symbols that are present 3690075Sobrien# so that we can not emit them into the final version script -- Solaris 3790075Sobrien# complains at us if we do. 3890075Sobrien 3990075Sobrienstate == "nm" && /^%%/ { 4090075Sobrien state = "ver"; 4190075Sobrien next; 4290075Sobrien} 4390075Sobrien 4490075Sobrienstate == "nm" && ($1 == "U" || $2 == "U") { 4590075Sobrien next; 4690075Sobrien} 4790075Sobrien 4890075Sobrienstate == "nm" && NF == 3 { 4990075Sobrien def[$3] = 1; 50117395Skan sawsymbol = 1; 5190075Sobrien next; 5290075Sobrien} 5390075Sobrien 5490075Sobrienstate == "nm" { 5590075Sobrien next; 5690075Sobrien} 5790075Sobrien 5890075Sobrien# Now we process a simplified variant of the Solaris symbol version 5990075Sobrien# script. We have one symbol per line, no semicolons, simple markers 6090075Sobrien# for beginning and ending each section, and %inherit markers for 6190075Sobrien# describing version inheritence. A symbol may appear in more than 6290075Sobrien# one symbol version, and the last seen takes effect. 63169689Skan# The magic version name '%exclude' causes all the symbols given that 64169689Skan# version to be dropped from the output (unless a later version overrides). 6590075Sobrien 6690075SobrienNF == 3 && $1 == "%inherit" { 6790075Sobrien inherit[$2] = $3; 6890075Sobrien next; 6990075Sobrien} 7090075Sobrien 7190075SobrienNF == 2 && $2 == "{" { 72169689Skan if ($1 != "%exclude") 73169689Skan libs[$1] = 1; 7490075Sobrien thislib = $1; 7590075Sobrien next; 7690075Sobrien} 7790075Sobrien 7890075Sobrien$1 == "}" { 7990075Sobrien thislib = ""; 8090075Sobrien next; 8190075Sobrien} 8290075Sobrien 8390075Sobrien{ 84169689Skan sym = prefix $1; 85169689Skan if (thislib != "%exclude") 86169689Skan ver[sym] = thislib; 87169689Skan else 88169689Skan delete ver[sym]; 8990075Sobrien next; 9090075Sobrien} 9190075Sobrien 9290075SobrienEND { 93117395Skan if (!sawsymbol) 94117395Skan { 95117395Skan print "No symbols seen -- broken or mis-installed nm?" | "cat 1>&2"; 96117395Skan exit 1; 97117395Skan } 9890075Sobrien for (l in libs) 9990075Sobrien output(l); 10090075Sobrien} 10190075Sobrien 10290075Sobrienfunction output(lib) { 10390075Sobrien if (done[lib]) 10490075Sobrien return; 10590075Sobrien done[lib] = 1; 10690075Sobrien if (inherit[lib]) 10790075Sobrien output(inherit[lib]); 10890075Sobrien 109122180Skan empty=1 11090075Sobrien for (sym in ver) 11190075Sobrien if ((ver[sym] == lib) && (sym in def)) 11296263Sobrien { 113122180Skan if (empty) 114117395Skan { 115122180Skan printf("%s {\n", lib); 116117395Skan printf(" global:\n"); 117122180Skan empty = 0; 118117395Skan } 11996263Sobrien printf("\t%s;\n", sym); 12096263Sobrien } 12190075Sobrien 122122180Skan if (empty) 123122180Skan { 124122180Skan for (l in libs) 125122180Skan if (inherit[l] == lib) 126122180Skan inherit[l] = inherit[lib]; 127122180Skan } 128122180Skan else if (inherit[lib]) 12990075Sobrien printf("} %s;\n", inherit[lib]); 13090075Sobrien else 13190075Sobrien printf ("\n local:\n\t*;\n};\n"); 13290075Sobrien} 133