Web lists-archives.com

Re: Rebuilding the entire Debian archive twice on arm64 hardware for fun and proft




$ python evil_linker_torture.py 2000 50 100 2000000

ok so it's pretty basic, and arguments of "2000 50 10 1000000"
resulted in around a 10-15 second linker phase, which top showed to be
getting up to around the 2-3GB resident memory range.  "2000 50 100
2000000" should start to make even a system with 64GB RAM start to
feel the pain.

evil_linker_torture.py N M O P generates N files with M functions
calling O randomly-selected functions where each file contains a
static char of size P that is *deliberately* put into the code segment
by being initialised with a non-zero value, exactly and precisely as
you should never do because... surpriiise! it adversely impacts the
binary size.

i'm just running the above, will hit "send" now in case i can't hit
ctrl-c in time on the linker phase... goodbye world... :)

l.
#!/usr/bin/env python

import sys
import random

maketemplate = """\
CC := gcc
CFILES:=$(shell ls | grep "\.c")
OBJS:=$(CFILES:%.c=%.o)
DEPS := $(CFILES:%.c=%.d)
CFLAGS := -g -g -g
LDFLAGS := -g -g -g

%.d: %.c
	$(CC) $(CFLAGS) -MM -o $@ $<

%.o: %.c
	$(CC) $(CFLAGS) -o $@ -c $<

#	$(CC) $(CFLAGS) -include $(DEPS) -o $@ $<

main: $(OBJS)
	$(CC) $(OBJS) $(LDFLAGS) -o main
"""

def gen_makefile():
    with open("Makefile", "w") as f:
        f.write(maketemplate)

def gen_headers(num_files, num_fns):
    for fnum in range(num_files):
        with open("hdr{}.h".format(fnum), "w") as f:
            for fn_num in range(num_fns):
                f.write("extern int fn_{}_{}(int arg1);\n".format(fnum, fn_num))

def gen_c_code(num_files, num_fns, num_calls, static_sz):
    for fnum in range(num_files):
        with open("src{}.c".format(fnum), "w") as f:
            for hfnum in range(num_files):
                f.write('#include "hdr{}.h"\n'.format(hfnum))
            f.write('static char data[%d] = {1};\n' % static_sz)
            for fn_num in range(num_fns):
                f.write("int fn_%d_%d(int arg1)\n{\n" % (fnum, fn_num))
                f.write("\tint arg = arg1 + 1;\n")
                for nc in range(num_calls):
                    cnum = random.randint(0, num_fns-1)
                    cfile = random.randint(0, num_files-1)
                    f.write("\targ += fn_{}_{}(arg);\n".format(cfile, cnum))
                f.write("\treturn arg;\n")
                f.write("}\n")
            if fnum != 0:
                continue
            f.write("int main(int argc, char *argv[])\n{\n")
            f.write("\tint arg = 0;\n")
            for nc in range(num_calls):
                cnum = random.randint(0, num_fns-1)
                cfile = random.randint(0, num_files-1)
                f.write("\targ += fn_{}_{}(arg);\n".format(cfile, cnum))
            f.write("\treturn 0;\n")
            f.write("}\n")

if __name__ == '__main__':
    num_files = int(sys.argv[1])
    num_fns = int(sys.argv[2])
    num_calls = int(sys.argv[3])
    static_sz = int(sys.argv[4])
    gen_makefile()
    gen_headers(num_files, num_fns)
    gen_c_code(num_files, num_fns, num_calls, static_sz)