reals_check/reals_check.ps1 (119 lines of code) (raw):
#Copyright (c) Microsoft. All rights reserved.
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
function Check-Symbols {
param(
[string] $lib
)
try {
[string]$output = cmd.exe /c dumpbin /ALL $lib
}
catch {
Write-Error "Unable to run dumpbin on given lib $lib"
return 2
}
# The list of public symbols in the dumpbin output is contained between these two symbols:
$start_token = "public symbols"
$end_token = "Archive member name"
try {
[int] $start = $output.IndexOf($start_token)
[int] $end = $output.IndexOf($end_token, $start)
# Isolating symbols from rest of dumpbin output
$symbol_text = ($output.Substring($start + $start_token.Length+1, $end-$start-$start_token.Length-1))
# Splitting text by whitespace, alternate tokens are symbols
$split_symbols = $symbol_text.Split('',[StringSplitOptions]::RemoveEmptyEntries)
}
catch {
Write-Error "Unable to parse dumpbin output for lib $lib"
return 2
}
# Detecting if symbol list was not generated by dumpbin
if($split_symbols.Length -lt 2) {
Write-Error "Unable to parse dumpbin output for lib $lib"
return 2
}
$real_prefix = "real_"
# hashset to store original symbols and real symbols
$symbol_table = New-Object -TypeName "System.Collections.Generic.HashSet[string]"
# list of symbols that have original and duplicate.
$duplicate_symbols = New-Object -TypeName "System.Collections.ArrayList"
$return_code = 0
for($i=0; $i -lt $split_symbols.Length; $i++){
# Skip even tokens because only odd tokens have symbols
if($i % 2 -ne 0) {
if($split_symbols[$i].StartsWith($real_prefix)) {
$real_symbol = $split_symbols[$i]
$symbol = $split_symbols[$i].Substring($real_prefix.Length)
} else {
$symbol = $split_symbols[$i]
$real_symbol = $real_prefix + $symbol
}
# Add original symbol and real symbol to hashset
if(-not ($symbol_table.Add($symbol) -and $symbol_table.Add($real_symbol))){
# If either of the adds fails, it means symbol was already present in hashset
$return_code = 1
[void]$duplicate_symbols.Add($symbol)
}
}
}
# Print duplicate symbols (if any) to stderr
if($duplicate_symbols.Count -gt 0){
Write-Error ("The following symbols have original and reals:`n"+($duplicate_symbols -join "`n"))
}
return $return_code
}
ForEach($lib in $args){
Write-Host "Checking lib $lib"
try {
$exit_code = Check-Symbols -lib $lib
}
catch {
Write-Error "Unable to check lib $lib."
return 2
}
if($exit_code -ne 0){
exit $exit_code
}
}
exit 0
<#
.SYNOPSIS
Checks library for presence of "[symbol]" and "real_[symbol]".
.DESCRIPTION
Checks library for presence of "[symbol]" and "real_[symbol]". Takes path to library as parameter.
.PARAMETER lib
Library to be checked.
.INPUTS
None.
.OUTPUTS
None.
Returns exit code 0 if no ("[symbol]", "real_[symbol]") pairs found in any library.
Returns exit code 1 if atleast 1 ("[symbol]", "real_[symbol]") pair found in a library. Prints names of symbols to stderr.
Returns exit code 2 if unable to determine for a library. Prints reason to stderror.
.EXAMPLE
PS> .\reals_check.ps1 lib_to_check_good.lib
PS> $lastexitcode
0
.EXAMPLE
PS> .\reals_check.ps1 lib_to_check_bad.lib
Check-Symbols : The following symbols are duplicate:
[
list of duplicate symbols
]
At {path_to_script}\reals_check.ps1:57 char:7
+ exit (Check-Symbols -lib $args[0])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Symbols
PS> $lastexitcode
1
.EXAMPLE
PS> .\reals_check.ps1 lib_to_check_nonexistent.lib
Check-Symbols : Unable to parse dumpbin output
At {path_to_script}\reals_check.ps1:57 char:7
+ exit (Check-Symbols -lib $args[0])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Symbols
PS> $lastexitcode
2
#>