brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · 8693a53 Raw
78 lines · plain
1## On Windows co-operative applications can be expected to open LLD's output2## with FILE_SHARE_DELETE included in the sharing mode. This allows us to link3## over the top of an existing file even if it is in use by another application.4 5# REQUIRES: system-windows, x866# RUN: echo '.globl _start; _start:' > %t.s7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-unknown %t.s -o %t.o8 9## FILE_SHARE_READ   = 110## FILE_SHARE_WRITE  = 211## FILE_SHARE_DELETE = 412 13# RUN:     %python %s %t.o 7 false14# RUN: not %python %s %t.o 3 false 2>&1 | FileCheck %s15# RUN:     %python %s %t.o 7 true16# RUN: not %python %s %t.o 3 true 2>&1 | FileCheck %s17# CHECK: error: failed to write output '{{.*}}': {{.*}}18 19import contextlib20import ctypes21from ctypes import wintypes as w22import os23import shutil24import subprocess25import platform26import sys27import time28 29object_file = sys.argv[1]30share_flags = int(sys.argv[2])31use_mmap = bool(sys.argv[3])32 33@contextlib.contextmanager34def open_with_share_flags(filename, share_flags):35    GENERIC_READ          = 0x8000000036    FILE_ATTRIBUTE_NORMAL = 0x8037    OPEN_EXISTING         = 0x338    INVALID_HANDLE_VALUE = w.HANDLE(-1).value39 40    CreateFileA = ctypes.windll.kernel32.CreateFileA41    CreateFileA.restype = w.HANDLE42    h = CreateFileA(filename.encode('mbcs'), GENERIC_READ, share_flags,43                    None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, None)44 45    assert h != INVALID_HANDLE_VALUE, 'Failed to open ' + filename46    try:47        yield48    finally:49        ctypes.windll.kernel32.CloseHandle(h)50 51## Ensure we have an empty directory for the output.52outdir = os.path.basename(__file__) + '.dir'53if os.path.exists(outdir):54    shutil.rmtree(outdir)55os.makedirs(outdir)56 57## Link on top of an open file.58elf = os.path.join(outdir, 'output_file.elf')59open(elf, 'wb').close()60with open_with_share_flags(elf, share_flags):61    args = ['ld.lld.exe', object_file, '-o', elf]62    if use_mmap:63        args.append("--mmap-output-file")64    subprocess.check_call(args)65 66## Check the linker wrote the output file.67with open(elf, 'rb') as f:68    assert f.read(4) == b'\x7fELF', "linker did not write output file correctly"69 70## Check no temp files are left around.71## It might take a while for Windows to remove them, so loop.72deleted = lambda: len(os.listdir(outdir)) == 173for _ in range(10):74    if not deleted():75        time.sleep (1)76 77assert deleted(), "temp file(s) not deleted after grace period"78