Fix export symbol test. (#4254)
* Fix export symbol test. The symbol export test does not check weak symbols, even though they are possibly exported. It also does not allow functions in the standard namespace even though it allows symbols on other namespaces. I've modified the check to look at the name of weakly defined function, and I've allowed functions in the standard namespace, functions in a local scope, and weak definitions of new and delete operators. Fixes #4250
This commit is contained in:
Родитель
f30465d2b5
Коммит
8ec9f456e6
|
@ -12,7 +12,13 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""Checks names of global exports from a library."""
|
||||
"""Ensures that all externally visible functions in the library have an appropriate name
|
||||
|
||||
Appropriate function names are:
|
||||
- names starting with spv,
|
||||
- anything in a namespace,
|
||||
- functions added by the protobuf compiler,
|
||||
- and weak definitions of new and delete."""
|
||||
|
||||
import os.path
|
||||
import re
|
||||
|
@ -46,14 +52,16 @@ def check_library(library):
|
|||
exports are namespaced or begin with spv (in either C or C++ styles)
|
||||
then return 0. Otherwise emit a message and return 1."""
|
||||
|
||||
# The pattern for a global symbol record
|
||||
symbol_pattern = re.compile(r'^[0-aA-Fa-f]+ g *F \.text.*[0-9A-Fa-f]+ +(.*)')
|
||||
# The pattern for an externally visible symbol record
|
||||
symbol_pattern = re.compile(r'^[0-aA-Fa-f]+ +([wg]) *F \.text.*[0-9A-Fa-f]+ +(.*)')
|
||||
|
||||
# Ok patterns are as follows, assuming Itanium name mangling:
|
||||
# spv[A-Z] : extern "C" symbol starting with spv
|
||||
# _ZN : something in a namespace
|
||||
# _ZSt : something in the standard namespace
|
||||
# _ZZN : something in a local scope and namespace
|
||||
# _Z[0-9]+spv[A-Z_] : C++ symbol starting with spv[A-Z_]
|
||||
symbol_ok_pattern = re.compile(r'^(spv[A-Z]|_ZN|_Z[0-9]+spv[A-Z_])')
|
||||
symbol_ok_pattern = re.compile(r'^(spv[A-Z]|_ZN|_ZSt|_ZZN|_Z[0-9]+spv[A-Z_])')
|
||||
|
||||
# In addition, the following pattern allowlists global functions that are added
|
||||
# by the protobuf compiler:
|
||||
|
@ -61,18 +69,22 @@ def check_library(library):
|
|||
# - InitDefaults_spvtoolsfuzz_2eproto()
|
||||
symbol_allowlist_pattern = re.compile(r'_Z[0-9]+(InitDefaults|AddDescriptors)_spvtoolsfuzz_2eprotov')
|
||||
|
||||
symbol_is_new_or_delete = re.compile(r'^(_Zna|_Znw|_Zdl|_Zda)')
|
||||
|
||||
seen = set()
|
||||
result = 0
|
||||
for line in command_output(['objdump', '-t', library], '.').split('\n'):
|
||||
match = symbol_pattern.search(line)
|
||||
if match:
|
||||
symbol = match.group(1)
|
||||
linkage = match.group(1)
|
||||
symbol = match.group(2)
|
||||
if symbol not in seen:
|
||||
seen.add(symbol)
|
||||
#print("look at '{}'".format(symbol))
|
||||
if not (symbol_allowlist_pattern.match(symbol) or symbol_ok_pattern.match(symbol)):
|
||||
print('{}: error: Unescaped exported symbol: {}'.format(PROG, symbol))
|
||||
result = 1
|
||||
if not (symbol_is_new_or_delete.match(symbol) and linkage == 'w'):
|
||||
if not (symbol_allowlist_pattern.match(symbol) or symbol_ok_pattern.match(symbol)):
|
||||
print('{}: error: Unescaped exported symbol: {}'.format(PROG, symbol))
|
||||
result = 1
|
||||
return result
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче