Skip to content

Commit b0b611c

Browse files
committed
add parts of system bitcode libraries when necessary, and refactor library inclusion decision code
1 parent 4833138 commit b0b611c

3 files changed

Lines changed: 58 additions & 9 deletions

File tree

emcc

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -991,20 +991,32 @@ try:
991991
for name, create, fix, library_symbols in [('libcxx', create_libcxx, fix_libcxx, libcxx_symbols),
992992
('libcxxabi', create_libcxxabi, fix_libcxxabi, libcxxabi_symbols),
993993
('dlmalloc', create_dlmalloc, fix_dlmalloc, dlmalloc_symbols)]:
994-
need = []
995-
has = []
994+
need = set()
995+
has = set()
996996
for temp_file in temp_files:
997997
symbols = shared.Building.llvm_nm(temp_file)
998998
for library_symbol in library_symbols:
999999
if library_symbol in symbols.undefs:
1000-
need.append(library_symbol)
1000+
need.add(library_symbol)
10011001
if library_symbol in symbols.defs:
1002-
has.append(library_symbol)
1003-
if DEBUG: print >> sys.stderr, 'emcc: considering including %s: we need |%s| and have |%s|' % (name, str(need), str(has))
1004-
if force or (need and not has):
1002+
has.add(library_symbol)
1003+
for haz in has: # remove symbols that are supplied by another of the inputs
1004+
if haz in need:
1005+
need.remove(haz)
1006+
if DEBUG: print >> sys.stderr, 'emcc: considering including %s: we need %s and have %s' % (name, str(need), str(has))
1007+
if force or len(need) > 0:
10051008
# We need to build and link the library in
10061009
if DEBUG: print >> sys.stderr, 'emcc: including %s' % name
1007-
extra_files_to_link.append(shared.Cache.get(name, create))
1010+
libfile = shared.Cache.get(name, create)
1011+
if len(has) > 0:
1012+
# remove the symbols we do not need
1013+
fixed = in_temp(uniquename(libfile)) + '.bc'
1014+
shutil.copyfile(libfile, fixed)
1015+
for haz in has:
1016+
if DEBUG: print >> sys.stderr, 'emcc: including: removing symbol "%s" that we have' % haz
1017+
shared.Building.remove_symbol(fixed, haz)
1018+
libfile = fixed
1019+
extra_files_to_link.append(libfile)
10081020
force = True
10091021
if fix:
10101022
fix()

tests/runner.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5779,6 +5779,39 @@ def test_dlmalloc(self):
57795779
]:
57805780
self.do_run(src.replace('{{{ NEW }}}', new).replace('{{{ DELETE }}}', delete), '*1,0*')
57815781

5782+
def test_dlmalloc_partial(self):
5783+
if self.emcc_args is None: return self.skip('only emcc will link in dlmalloc')
5784+
# present part of the symbols of dlmalloc, not all
5785+
src = open(path_from_root('tests', 'new.cpp')).read().replace('{{{ NEW }}}', 'new int').replace('{{{ DELETE }}}', 'delete') + '''
5786+
void *
5787+
operator new(size_t size)
5788+
{
5789+
printf("new %d!\\n", size);
5790+
return malloc(size);
5791+
}
5792+
'''
5793+
self.do_run(src, 'new 4!\n*1,0*')
5794+
5795+
def test_dlmalloc_partial_2(self):
5796+
if self.emcc_args is None or 'SAFE_HEAP' in str(self.emcc_args): return self.skip('only emcc will link in dlmalloc, and we do unsafe stuff')
5797+
# present part of the symbols of dlmalloc, not all. malloc is harder to link than new which is weak.
5798+
src = r'''
5799+
#include <stdio.h>
5800+
#include <stdlib.h>
5801+
void *malloc(size_t size)
5802+
{
5803+
return (void*)123;
5804+
}
5805+
int main() {
5806+
void *x = malloc(10);
5807+
printf("got %p\n", x);
5808+
free(x);
5809+
printf("freed the faker\n");
5810+
return 1;
5811+
}
5812+
'''
5813+
self.do_run(src, 'got 0x7b\nfreed')
5814+
57825815
def test_libcxx(self):
57835816
self.do_run(open(path_from_root('tests', 'hashtest.cpp')).read(),
57845817
'june -> 30\nPrevious (in alphabetical order) is july\nNext (in alphabetical order) is march')

tools/shared.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,11 @@ def open_make_err(i, mode='r'):
706706
os.chdir(old_dir)
707707
return generated_libs
708708

709+
@staticmethod
710+
def remove_symbol(filename, symbol):
711+
Popen([LLVM_EXTRACT, filename, '-delete', '-glob=' + symbol, '-o', filename], stderr=PIPE).communicate()
712+
Popen([LLVM_EXTRACT, filename, '-delete', '-func=' + symbol, '-o', filename], stderr=PIPE).communicate()
713+
709714
@staticmethod
710715
def link(files, target, remove_duplicates=False):
711716
actual_files = []
@@ -775,8 +780,7 @@ def link(files, target, remove_duplicates=False):
775780
print >> sys.stderr, 'emcc: warning: removing duplicates in', actual
776781
for dupe in dupes:
777782
print >> sys.stderr, 'emcc: warning: removing duplicate', dupe
778-
Popen([LLVM_EXTRACT, actual, '-delete', '-glob=' + dupe, '-o', actual], stderr=PIPE).communicate()
779-
Popen([LLVM_EXTRACT, actual, '-delete', '-func=' + dupe, '-o', actual], stderr=PIPE).communicate()
783+
Building.remove_symbol(actual, dupe)
780784
Popen([LLVM_EXTRACT, actual, '-delete', '-glob=.str', '-o', actual], stderr=PIPE).communicate() # garbage that appears here
781785
seen_symbols = seen_symbols.union(symbols.defs)
782786

0 commit comments

Comments
 (0)