15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#!/usr/bin/perl 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 1. Redistributions of source code must retain the above copyright 10fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch# notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 2. Redistributions in binary form must reproduce the above copyright 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# notice, this list of conditions and the following disclaimer in the 13fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch# documentation and/or other materials provided with the distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# its contributors may be used to endorse or promote products derived 16fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch# from this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# "check-for-global-initializers" script for WebKit Open Source Project 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Intended to be invoked from an Xcode build step to check if there are 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# any global initializers in a target. 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)use warnings; 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)use strict; 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)use File::Basename; 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)sub touch($); 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)sub demangle($); 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $arch = $ENV{'CURRENT_ARCH'}; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $configuration = $ENV{'CONFIGURATION'}; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $target = $ENV{'TARGET_NAME'}; 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $variant = $ENV{'CURRENT_VARIANT'}; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'}; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'}; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)$arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)$variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}"; 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp"; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $buildTimestampAge = -M $buildTimestampPath; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $scriptAge = -M $0; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $list = $ENV{"LINK_FILE_LIST_${variant}_${arch}"}; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)if (!open LIST, $list) { 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) print "ERROR: Could not open $list\n"; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) exit 1; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my @files = <LIST>; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)chomp @files; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)close LIST; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)my $sawError = 0; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)for my $file (sort @files) { 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (defined $buildTimestampAge && $buildTimestampAge < $scriptAge) { 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my $fileAge = -M $file; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if defined $fileAge && $fileAge > $buildTimestampAge; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!open NM, "(nm '$file' | sed 's/^/STDOUT:/') 2>&1 |") { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) print "ERROR: Could not open $file\n"; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $sawError = 1; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my $sawGlobal = 0; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my @globals; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (<NM>) { 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (/^STDOUT:/) { 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my $line = $_; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($line =~ /__GLOBAL__I(.+)$/) { 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $sawGlobal = 1; 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) push(@globals, demangle($1)); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) print STDERR if $_ ne "nm: no name list\n"; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) close NM; 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($sawGlobal) { 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my $shortName = $file; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $shortName =~ s/.*\///; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # Special cases for files that have initializers in debug builds. 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($configuration eq "Debug" or $variant eq "debug" or $debugRoot) { 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($target eq "JavaScriptCore") { 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "AllInOneFile.o"; 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "Opcode.o"; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "Structure.o"; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "nodes.o"; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($target eq "WebCore") { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "BidiRun.o"; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "CachedPage.o"; 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "CachedResource.o"; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "FEGaussianBlur.o"; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "Frame.o"; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "JSCustomSQLTransactionCallback.o"; 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "JSLazyEventListener.o"; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "Node.o"; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "Page.o"; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "Range.o"; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "RenderObject.o"; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "SVGElementInstance.o"; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "SubresourceLoader.o"; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "XMLHttpRequest.o"; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($target eq "WebKit") { 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "HostedNetscapePluginStream.o"; 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "NetscapePluginInstanceProxy.o"; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ($target eq "WebKit2") { 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "WebContext.o"; 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "WebFrame.o"; 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "WebPage.o"; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) next if $shortName eq "WebPageProxy.o"; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) print "ERROR: $shortName has one or more global initializers in it! ($file), near @globals\n"; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $sawError = 1; 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)if ($sawError and !$coverageBuild) { 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unlink $executablePath; 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) exit 1; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)touch($buildTimestampPath); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)exit 0; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)sub touch($) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my ($path) = @_; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) open(TOUCH, ">", $path) or die "$!"; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) close(TOUCH); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)sub demangle($) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my ($symbol) = @_; 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!open FILT, "c++filt $symbol |") { 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) print "ERROR: Could not open c++filt\n"; 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) my $result = <FILT>; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) close FILT; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) chomp $result; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return $result; 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 168