Skip to content

Commit 6b5bced

Browse files
committed
Don't depend on llvm-nm to detect archive indexes
There is an llvm but that mean that certain binary files get mistaken for COFF object which means llvm-nm will error out: https://bugs.llvm.org/show_bug.cgi?id=44683 Instead write out own trivial ar parser to detect the presence of that index. Fixes: #10195
1 parent d2148d0 commit 6b5bced

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

emcc.py

+26-11
Original file line numberDiff line numberDiff line change
@@ -480,21 +480,36 @@ def do_emscripten(infile, memfile):
480480
return outfile
481481

482482

483+
def is_ar_file_with_missing_index(archive_file):
484+
# We parse the archive header outselves because llvm-nm --print-armap is slower and less
485+
# reliable.
486+
# See: https://github.com/emscripten-core/emscripten/issues/10195
487+
archive_header = b'!<arch>\n'
488+
file_header_size = 60
489+
490+
with open(archive_file, 'rb') as f:
491+
header = f.read(len(archive_header))
492+
if header != archive_header:
493+
# This is not even an ar file
494+
return False
495+
file_header = f.read(file_header_size)
496+
if len(file_header) != file_header_size:
497+
# We don't have any file entires at all so we don't consider the index missing
498+
return False
499+
500+
name = file_header[:16].strip()
501+
# If '/' is the name of the first file we have an index
502+
return name != '/'
503+
504+
483505
def ensure_archive_index(archive_file):
484506
# Fastcomp linking works without archive indexes.
485507
if not shared.Settings.WASM_BACKEND or not shared.Settings.AUTO_ARCHIVE_INDEXES:
486508
return
487-
# Ignore stderr since llvm-nm prints "no symbols" to stderr for each object that has no symbols
488-
stdout = run_process([shared.LLVM_NM, '--print-armap', archive_file], stdout=PIPE, stderr=PIPE).stdout
489-
stdout = stdout.strip()
490-
# Ignore empty archives
491-
if not stdout:
492-
return
493-
if stdout.startswith('Archive map\n') or stdout.startswith('Archive index\n'):
494-
return
495-
shared.warning('%s: archive is missing an index; Use emar when creating libraries to ensure an index is created', archive_file)
496-
shared.warning('%s: adding index', archive_file)
497-
run_process([shared.LLVM_RANLIB, archive_file])
509+
if is_ar_file_with_missing_index(archive_file):
510+
shared.warning('%s: archive is missing an index; Use emar when creating libraries to ensure an index is created', archive_file)
511+
shared.warning('%s: adding index', archive_file)
512+
run_process([shared.LLVM_RANLIB, archive_file])
498513

499514

500515
#

tests/test_other.py

+10
Original file line numberDiff line numberDiff line change
@@ -8728,6 +8728,16 @@ def test_archive_no_index(self):
87288728
# The default behavior is to add archive indexes automatically.
87298729
run_process([PYTHON, EMCC, 'libfoo.a', 'hello_world.o'])
87308730

8731+
def test_archive_non_objects(self):
8732+
create_test_file('file.txt', 'test file')
8733+
# llvm-nm has issues with files that start with two or more null bytes since it thinks they
8734+
# are COFF files. Ensure that we correctly ignore such files when we process them.
8735+
create_test_file('zeros.bin', '\0\0\0\0')
8736+
run_process([PYTHON, EMCC, '-c', path_from_root('tests', 'hello_world.c')])
8737+
# No index added.
8738+
run_process([PYTHON, EMAR, 'crS', 'libfoo.a', 'file.txt', 'zeros.bin', 'hello_world.o'])
8739+
run_process([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), 'libfoo.a'])
8740+
87318741
def test_flag_aliases(self):
87328742
def assert_aliases_match(flag1, flag2, flagarg, extra_args):
87338743
results = {}

0 commit comments

Comments
 (0)