From b6f76b8fb2f436e1752de585b6960ab995d4c374 Mon Sep 17 00:00:00 2001 From: Lionel Sambuc Date: Mon, 29 Sep 2014 14:52:06 +0200 Subject: [PATCH] Initial import of lld Change-Id: I3ba67eaea52b3a6670b70203cd4d98a3c9c41a46 --- external/bsd/llvm/dist/lld/.arcconfig | 4 + external/bsd/llvm/dist/lld/CMakeLists.txt | 169 +++ external/bsd/llvm/dist/lld/LICENSE.TXT | 62 + external/bsd/llvm/dist/lld/README.md | 10 + .../dist/lld/cmake/modules/FindVTune.cmake | 31 + external/bsd/llvm/dist/lld/docs/C++11.rst | 35 + external/bsd/llvm/dist/lld/docs/Driver.rst | 79 + external/bsd/llvm/dist/lld/docs/Makefile | 155 ++ external/bsd/llvm/dist/lld/docs/README.txt | 12 + external/bsd/llvm/dist/lld/docs/Readers.rst | 172 +++ .../llvm/dist/lld/docs/_static/favicon.ico | Bin 0 -> 1150 bytes .../lld/docs/_templates/indexsidebar.html | 4 + .../llvm/dist/lld/docs/_templates/layout.html | 12 + external/bsd/llvm/dist/lld/docs/conf.py | 251 ++++ external/bsd/llvm/dist/lld/docs/design.rst | 470 ++++++ .../bsd/llvm/dist/lld/docs/development.rst | 48 + .../llvm/dist/lld/docs/getting_started.rst | 106 ++ external/bsd/llvm/dist/lld/docs/hello.png | Bin 0 -> 27616 bytes external/bsd/llvm/dist/lld/docs/index.rst | 82 + .../llvm/dist/lld/docs/llvm-theme/layout.html | 22 + .../lld/docs/llvm-theme/static/contents.png | Bin 0 -> 202 bytes .../dist/lld/docs/llvm-theme/static/llvm.css | 345 +++++ .../dist/lld/docs/llvm-theme/static/logo.png | Bin 0 -> 9865 bytes .../lld/docs/llvm-theme/static/navigation.png | Bin 0 -> 218 bytes .../llvm/dist/lld/docs/llvm-theme/theme.conf | 4 + external/bsd/llvm/dist/lld/docs/make.bat | 190 +++ .../bsd/llvm/dist/lld/docs/open_projects.rst | 13 + .../bsd/llvm/dist/lld/docs/sphinx_intro.rst | 147 ++ .../dist/lld/include/lld/Core/AbsoluteAtom.h | 43 + .../lld/include/lld/Core/ArchiveLibraryFile.h | 48 + .../bsd/llvm/dist/lld/include/lld/Core/Atom.h | 84 ++ .../dist/lld/include/lld/Core/DefinedAtom.h | 357 +++++ .../llvm/dist/lld/include/lld/Core/Error.h | 84 ++ .../bsd/llvm/dist/lld/include/lld/Core/File.h | 251 ++++ .../dist/lld/include/lld/Core/InputGraph.h | 411 +++++ .../lld/include/lld/Core/Instrumentation.h | 133 ++ .../bsd/llvm/dist/lld/include/lld/Core/LLVM.h | 92 ++ .../lld/include/lld/Core/LinkingContext.h | 378 +++++ .../llvm/dist/lld/include/lld/Core/Parallel.h | 271 ++++ .../bsd/llvm/dist/lld/include/lld/Core/Pass.h | 118 ++ .../dist/lld/include/lld/Core/PassManager.h | 43 + .../dist/lld/include/lld/Core/Reference.h | 112 ++ .../llvm/dist/lld/include/lld/Core/Resolver.h | 128 ++ .../dist/lld/include/lld/Core/STDExtras.h | 33 + .../lld/include/lld/Core/SharedLibraryAtom.h | 57 + .../lld/include/lld/Core/SharedLibraryFile.h | 42 + .../dist/lld/include/lld/Core/SymbolTable.h | 110 ++ .../llvm/dist/lld/include/lld/Core/TODO.txt | 17 + .../dist/lld/include/lld/Core/UndefinedAtom.h | 74 + .../llvm/dist/lld/include/lld/Core/range.h | 739 +++++++++ .../lld/include/lld/Driver/CoreInputGraph.h | 79 + .../lld/include/lld/Driver/DarwinInputGraph.h | 82 + .../llvm/dist/lld/include/lld/Driver/Driver.h | 135 ++ .../lld/include/lld/Driver/GnuLdInputGraph.h | 187 +++ .../include/lld/Driver/WinLinkInputGraph.h | 101 ++ .../dist/lld/include/lld/Passes/LayoutPass.h | 106 ++ .../include/lld/Passes/RoundTripNativePass.h | 41 + .../include/lld/Passes/RoundTripYAMLPass.h | 41 + .../lld/include/lld/ReaderWriter/AtomLayout.h | 41 + .../lld/ReaderWriter/CoreLinkingContext.h | 45 + .../lld/ReaderWriter/ELFLinkingContext.h | 246 +++ .../include/lld/ReaderWriter/FileArchive.h | 176 +++ .../include/lld/ReaderWriter/LinkerScript.h | 228 +++ .../include/lld/ReaderWriter/MachOFormat.hpp | 627 ++++++++ .../lld/ReaderWriter/MachOLinkingContext.h | 174 +++ .../lld/ReaderWriter/PECOFFLinkingContext.h | 338 +++++ .../lld/include/lld/ReaderWriter/Reader.h | 56 + .../lld/ReaderWriter/ReaderLinkerScript.h | 34 + .../ReaderWriter/RelocationHelperFunctions.h | 53 + .../lld/include/lld/ReaderWriter/Simple.h | 204 +++ .../lld/include/lld/ReaderWriter/Writer.h | 52 + external/bsd/llvm/dist/lld/lib/CMakeLists.txt | 4 + .../bsd/llvm/dist/lld/lib/Core/CMakeLists.txt | 17 + .../llvm/dist/lld/lib/Core/DefinedAtom.cpp | 84 ++ external/bsd/llvm/dist/lld/lib/Core/Error.cpp | 129 ++ external/bsd/llvm/dist/lld/lib/Core/File.cpp | 30 + .../bsd/llvm/dist/lld/lib/Core/InputGraph.cpp | 178 +++ .../llvm/dist/lld/lib/Core/LinkingContext.cpp | 113 ++ .../llvm/dist/lld/lib/Core/PassManager.cpp | 24 + .../bsd/llvm/dist/lld/lib/Core/Resolver.cpp | 493 ++++++ .../llvm/dist/lld/lib/Core/SymbolTable.cpp | 364 +++++ external/bsd/llvm/dist/lld/lib/Core/TODO.txt | 18 + .../llvm/dist/lld/lib/Driver/CMakeLists.txt | 36 + .../llvm/dist/lld/lib/Driver/CoreDriver.cpp | 159 ++ .../llvm/dist/lld/lib/Driver/CoreOptions.td | 15 + .../dist/lld/lib/Driver/DarwinLdDriver.cpp | 267 ++++ .../dist/lld/lib/Driver/DarwinLdOptions.td | 79 + .../bsd/llvm/dist/lld/lib/Driver/Driver.cpp | 137 ++ .../llvm/dist/lld/lib/Driver/GnuLdDriver.cpp | 362 +++++ .../llvm/dist/lld/lib/Driver/GnuLdOptions.td | 240 +++ .../dist/lld/lib/Driver/UniversalDriver.cpp | 183 +++ .../lld/lib/Driver/UniversalDriverOptions.td | 16 + .../dist/lld/lib/Driver/WinLinkDriver.cpp | 976 ++++++++++++ .../dist/lld/lib/Driver/WinLinkOptions.td | 103 ++ .../llvm/dist/lld/lib/Passes/CMakeLists.txt | 9 + .../bsd/llvm/dist/lld/lib/Passes/GOTPass.cpp | 108 ++ .../llvm/dist/lld/lib/Passes/LayoutPass.cpp | 569 +++++++ .../lld/lib/Passes/RoundTripNativePass.cpp | 48 + .../dist/lld/lib/Passes/RoundTripYAMLPass.cpp | 53 + .../llvm/dist/lld/lib/Passes/StubsPass.cpp | 66 + .../dist/lld/lib/ReaderWriter/CMakeLists.txt | 19 + .../lib/ReaderWriter/CoreLinkingContext.cpp | 314 ++++ .../lib/ReaderWriter/ELF/ArrayOrderPass.cpp | 44 + .../lld/lib/ReaderWriter/ELF/ArrayOrderPass.h | 26 + .../dist/lld/lib/ReaderWriter/ELF/Atoms.h | 1026 +++++++++++++ .../lld/lib/ReaderWriter/ELF/CMakeLists.txt | 26 + .../dist/lld/lib/ReaderWriter/ELF/Chunk.h | 98 ++ .../dist/lld/lib/ReaderWriter/ELF/CreateELF.h | 109 ++ .../lld/lib/ReaderWriter/ELF/DefaultLayout.h | 866 +++++++++++ .../ReaderWriter/ELF/DefaultTargetHandler.h | 65 + .../lld/lib/ReaderWriter/ELF/DynamicFile.h | 137 ++ .../ReaderWriter/ELF/DynamicLibraryWriter.h | 98 ++ .../ReaderWriter/ELF/ELFLinkingContext.cpp | 193 +++ .../lib/ReaderWriter/ELF/ExecutableWriter.h | 145 ++ .../llvm/dist/lld/lib/ReaderWriter/ELF/File.h | 818 ++++++++++ .../lld/lib/ReaderWriter/ELF/HeaderChunks.h | 352 +++++ .../ReaderWriter/ELF/Hexagon/CMakeLists.txt | 9 + .../ELF/Hexagon/HexagonExecutableAtoms.h | 29 + .../ELF/Hexagon/HexagonLinkingContext.cpp | 252 ++++ .../ELF/Hexagon/HexagonLinkingContext.h | 72 + .../ELF/Hexagon/HexagonRelocationFunctions.h | 49 + .../ELF/Hexagon/HexagonRelocationHandler.cpp | 355 +++++ .../ELF/Hexagon/HexagonRelocationHandler.h | 41 + .../ELF/Hexagon/HexagonSectionChunks.h | 87 ++ .../ReaderWriter/ELF/Hexagon/HexagonTarget.h | 10 + .../ELF/Hexagon/HexagonTargetHandler.cpp | 300 ++++ .../ELF/Hexagon/HexagonTargetHandler.h | 227 +++ .../ELF/Hexagon/HexagonV4Encodings.h | 601 ++++++++ .../dist/lld/lib/ReaderWriter/ELF/Layout.h | 62 + .../lib/ReaderWriter/ELF/OutputELFWriter.h | 430 ++++++ .../lib/ReaderWriter/ELF/PPC/CMakeLists.txt | 8 + .../ELF/PPC/PPCLinkingContext.cpp | 46 + .../ReaderWriter/ELF/PPC/PPCLinkingContext.h | 40 + .../lld/lib/ReaderWriter/ELF/PPC/PPCTarget.h | 10 + .../ReaderWriter/ELF/PPC/PPCTargetHandler.cpp | 72 + .../ReaderWriter/ELF/PPC/PPCTargetHandler.h | 55 + .../dist/lld/lib/ReaderWriter/ELF/Reader.cpp | 136 ++ .../lld/lib/ReaderWriter/ELF/SectionChunks.h | 1332 +++++++++++++++++ .../lld/lib/ReaderWriter/ELF/SegmentChunks.h | 606 ++++++++ .../dist/lld/lib/ReaderWriter/ELF/TODO.txt | 17 + .../lld/lib/ReaderWriter/ELF/TargetHandler.h | 126 ++ .../lld/lib/ReaderWriter/ELF/TargetLayout.h | 30 + .../dist/lld/lib/ReaderWriter/ELF/Targets.h | 18 + .../dist/lld/lib/ReaderWriter/ELF/Writer.cpp | 68 + .../dist/lld/lib/ReaderWriter/ELF/Writer.h | 38 + .../lib/ReaderWriter/ELF/X86/CMakeLists.txt | 8 + .../ELF/X86/X86LinkingContext.cpp | 48 + .../ReaderWriter/ELF/X86/X86LinkingContext.h | 45 + .../lld/lib/ReaderWriter/ELF/X86/X86Target.h | 10 + .../ReaderWriter/ELF/X86/X86TargetHandler.cpp | 71 + .../ReaderWriter/ELF/X86/X86TargetHandler.h | 55 + .../ReaderWriter/ELF/X86_64/CMakeLists.txt | 10 + .../ELF/X86_64/X86_64LinkingContext.cpp | 196 +++ .../ELF/X86_64/X86_64LinkingContext.h | 88 ++ .../ELF/X86_64/X86_64RelocationHandler.cpp | 147 ++ .../ELF/X86_64/X86_64RelocationHandler.h | 42 + .../ELF/X86_64/X86_64RelocationPass.cpp | 462 ++++++ .../ELF/X86_64/X86_64RelocationPass.h | 32 + .../ReaderWriter/ELF/X86_64/X86_64Target.h | 10 + .../ELF/X86_64/X86_64TargetHandler.cpp | 29 + .../ELF/X86_64/X86_64TargetHandler.h | 54 + .../lld/lib/ReaderWriter/LinkerScript.cpp | 289 ++++ .../lld/lib/ReaderWriter/MachO/CMakeLists.txt | 14 + .../ReaderWriter/MachO/ExecutableAtoms.hpp | 48 + .../lld/lib/ReaderWriter/MachO/GOTPass.hpp | 51 + .../MachO/MachOLinkingContext.cpp | 306 ++++ .../ReaderWriter/MachO/MachONormalizedFile.h | 279 ++++ .../MachO/MachONormalizedFileBinaryReader.cpp | 310 ++++ .../MachO/MachONormalizedFileBinaryUtils.h | 293 ++++ .../MachO/MachONormalizedFileBinaryWriter.cpp | 971 ++++++++++++ .../MachO/MachONormalizedFileFromAtoms.cpp | 820 ++++++++++ .../MachO/MachONormalizedFileYAML.cpp | 626 ++++++++ .../lib/ReaderWriter/MachO/ReferenceKinds.cpp | 405 +++++ .../lib/ReaderWriter/MachO/ReferenceKinds.h | 151 ++ .../lld/lib/ReaderWriter/MachO/StubAtoms.hpp | 71 + .../lib/ReaderWriter/MachO/StubAtoms_x86.hpp | 199 +++ .../ReaderWriter/MachO/StubAtoms_x86_64.hpp | 199 +++ .../lld/lib/ReaderWriter/MachO/StubsPass.hpp | 173 +++ .../lib/ReaderWriter/MachO/WriterMachO.cpp | 67 + .../lib/ReaderWriter/Native/CMakeLists.txt | 8 + .../ReaderWriter/Native/NativeFileFormat.h | 248 +++ .../lib/ReaderWriter/Native/ReaderNative.cpp | 942 ++++++++++++ .../lib/ReaderWriter/Native/WriterNative.cpp | 507 +++++++ .../dist/lld/lib/ReaderWriter/PECOFF/Atoms.h | 349 +++++ .../lib/ReaderWriter/PECOFF/CMakeLists.txt | 11 + .../ReaderWriter/PECOFF/GroupedSectionsPass.h | 145 ++ .../lld/lib/ReaderWriter/PECOFF/IdataPass.h | 372 +++++ .../PECOFF/LinkerGeneratedSymbolFile.h | 35 + .../PECOFF/PECOFFLinkingContext.cpp | 211 +++ .../lib/ReaderWriter/PECOFF/ReaderCOFF.cpp | 947 ++++++++++++ .../PECOFF/ReaderImportHeader.cpp | 320 ++++ .../ReaderWriter/PECOFF/ReaderImportHeader.h | 34 + .../lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 1000 +++++++++++++ .../llvm/dist/lld/lib/ReaderWriter/Reader.cpp | 20 + .../lib/ReaderWriter/ReaderLinkerScript.cpp | 98 ++ .../llvm/dist/lld/lib/ReaderWriter/Writer.cpp | 23 + .../lld/lib/ReaderWriter/YAML/CMakeLists.txt | 7 + .../ReaderWriter/YAML/ReaderWriterYAML.cpp | 1312 ++++++++++++++++ .../bsd/llvm/dist/lld/test/CMakeLists.txt | 87 ++ .../llvm/dist/lld/test/Driver/lib-search.test | 6 + .../lld/test/Driver/libsearch-inputGraph.test | 44 + .../dist/lld/test/Driver/trivial-driver.test | 5 + .../dist/lld/test/Driver/undef-basic.objtxt | 22 + external/bsd/llvm/dist/lld/test/Unit/lit.cfg | 23 + .../llvm/dist/lld/test/Unit/lit.site.cfg.in | 25 + .../dist/lld/test/core/absolute-basic.objtxt | 23 + .../dist/lld/test/core/absolute-local.objtxt | 25 + .../dist/lld/test/core/archive-basic.objtxt | 45 + .../dist/lld/test/core/archive-chain.objtxt | 72 + .../test/core/archive-tentdef-search.objtxt | 43 + .../lld/test/core/auto-hide-coalesce.objtxt | 60 + .../lld/test/core/constants-coalesce.objtxt | 60 + .../lld/test/core/cstring-coalesce.objtxt | 41 + .../dist/lld/test/core/custom-section.objtxt | 34 + .../test/core/dead-strip-attributes.objtxt | 29 + .../lld/test/core/dead-strip-basic.objtxt | 62 + .../lld/test/core/dead-strip-globals.objtxt | 60 + .../bsd/llvm/dist/lld/test/core/empty.objtxt | 11 + .../lld/test/core/error-atom-attribute.objtxt | 19 + .../core/error-atom-content-byte-value.objtxt | 18 + .../test/core/error-atom-content-bytes.objtxt | 19 + .../dist/lld/test/core/error-atom-type.objtxt | 19 + ...error-atom-undefined-wrong-attribue.objtxt | 17 + .../core/error-duplicate-absolutes.objtxt | 24 + .../lld/test/core/error-file-attribute.objtxt | 17 + .../test/core/error-fixup-attribute.objtxt | 21 + .../lld/test/core/error-fixup-target.objtxt | 26 + .../dist/lld/test/core/fixups-addend.objtxt | 50 + .../lld/test/core/fixups-dup-named.objtxt | 31 + .../dist/lld/test/core/fixups-named.objtxt | 36 + .../dist/lld/test/core/fixups-unnamed.objtxt | 40 + .../lld/test/core/ingroup-test-big.objtxt | 57 + .../lld/test/core/ingroup-test-loop.objtxt | 20 + .../ingroup-test-with-layout-after.objtxt | 50 + .../dist/lld/test/core/ingroup-test.objtxt | 38 + .../dist/lld/test/core/inline-coalesce.objtxt | 31 + .../lld/test/core/layout-error-test.objtxt | 22 + .../lld/test/core/layout-transitivity.objtxt | 34 + .../lld/test/core/layoutafter-test.objtxt | 30 + .../lld/test/core/layoutbefore-test.objtxt | 25 + .../lld/test/core/multiple-def-error.objtxt | 19 + .../dist/lld/test/core/pass-got-basic.objtxt | 82 + .../lld/test/core/pass-stubs-basic.objtxt | 47 + .../dist/lld/test/core/permissions.objtxt | 57 + .../lld/test/core/section-position.objtxt | 85 ++ .../lld/test/core/shared-library-basic.objtxt | 40 + .../test/core/shared-library-coalesce.objtxt | 84 ++ .../llvm/dist/lld/test/core/tent-merge.objtxt | 25 + .../lld/test/core/undef-coalesce-error.objtxt | 47 + .../dist/lld/test/core/undef-coalesce.objtxt | 42 + .../dist/lld/test/core/undef-fallback.objtxt | 18 + .../lld/test/core/undef-weak-coalesce.objtxt | 83 + .../dist/lld/test/core/weak-coalesce.objtxt | 30 + .../dist/lld/test/darwin/hello-world.objtxt | 36 + .../lld/test/elf/Hexagon/Inputs/dynobj-data.c | 3 + .../dist/lld/test/elf/Hexagon/Inputs/dynobj.c | 26 + .../test/elf/Hexagon/Inputs/got-plt-order.c | 6 + .../test/elf/Hexagon/Inputs/initfini-option.c | 13 + .../elf/Hexagon/Inputs/use-shared.hexagon | Bin 0 -> 872 bytes .../lld/test/elf/Hexagon/dynlib-data.test | 9 + .../lld/test/elf/Hexagon/dynlib-gotoff.test | 128 ++ .../lld/test/elf/Hexagon/dynlib-hash.test | 9 + .../lld/test/elf/Hexagon/dynlib-syms.test | 8 + .../dist/lld/test/elf/Hexagon/dynlib.test | 33 + .../elf/Hexagon/hexagon-got-plt-order.test | 5 + .../test/elf/Hexagon/hexagon-plt-setup.test | 15 + .../lld/test/elf/Hexagon/initfini-option.test | 21 + .../lld/test/elf/Hexagon/maxalignment.test | 8 + .../dist/lld/test/elf/Hexagon/rela-order.test | 9 + .../dist/lld/test/elf/Hexagon/sda-base.test | 4 + .../dist/lld/test/elf/Inputs/abs-test.i386 | Bin 0 -> 504 bytes .../dist/lld/test/elf/Inputs/bar.o.x86-64 | Bin 0 -> 1240 bytes .../lld/test/elf/Inputs/branch-test.hexagon | Bin 0 -> 700 bytes .../dist/lld/test/elf/Inputs/branch-test.ppc | Bin 0 -> 852 bytes .../test/elf/Inputs/constants-merge.x86-64 | Bin 0 -> 1232 bytes .../dist/lld/test/elf/Inputs/constdata.x86-64 | Bin 0 -> 1688 bytes .../dist/lld/test/elf/Inputs/foo.o.x86-64 | Bin 0 -> 1240 bytes .../dist/lld/test/elf/Inputs/globalconst.c | 2 + .../lld/test/elf/Inputs/globalconst.o.x86-64 | Bin 0 -> 1072 bytes .../llvm/dist/lld/test/elf/Inputs/gotpcrel.S | 11 + .../dist/lld/test/elf/Inputs/gotpcrel.x86-64 | Bin 0 -> 904 bytes .../bsd/llvm/dist/lld/test/elf/Inputs/ifunc.S | 21 + .../llvm/dist/lld/test/elf/Inputs/ifunc.cpp | 3 + .../dist/lld/test/elf/Inputs/ifunc.cpp.x86-64 | Bin 0 -> 1224 bytes .../dist/lld/test/elf/Inputs/ifunc.x86-64 | Bin 0 -> 912 bytes .../lld/test/elf/Inputs/init_array.x86-64 | Bin 0 -> 3440 bytes .../dist/lld/test/elf/Inputs/mainobj.x86_64 | Bin 0 -> 1360 bytes .../test/elf/Inputs/object-test.elf-hexagon | Bin 0 -> 1532 bytes .../lld/test/elf/Inputs/object-test.elf-i386 | Bin 0 -> 1784 bytes .../llvm/dist/lld/test/elf/Inputs/phdr.i386 | Bin 0 -> 17536 bytes .../Inputs/quickdata-sort-test.o.elf-hexagon | Bin 0 -> 1385 bytes .../quickdata-sortcommon-test.o.elf-hexagon | Bin 0 -> 1469 bytes .../elf/Inputs/quickdata-test.elf-hexagon | Bin 0 -> 891 bytes .../lld/test/elf/Inputs/reloc-test.elf-i386 | Bin 0 -> 1076 bytes .../dist/lld/test/elf/Inputs/reloc-xb.x86 | Bin 0 -> 568 bytes .../dist/lld/test/elf/Inputs/reloc-xt.x86 | Bin 0 -> 548 bytes .../lld/test/elf/Inputs/relocs-dynamic.x86-64 | Bin 0 -> 864 bytes .../dist/lld/test/elf/Inputs/relocs.x86-64 | Bin 0 -> 1536 bytes .../lld/test/elf/Inputs/rodata-test.hexagon | Bin 0 -> 669 bytes .../dist/lld/test/elf/Inputs/rodata-test.i386 | Bin 0 -> 537 bytes .../lld/test/elf/Inputs/section-test.i386 | Bin 0 -> 717 bytes .../llvm/dist/lld/test/elf/Inputs/shared.c | 16 + .../dist/lld/test/elf/Inputs/shared.so-x86-64 | Bin 0 -> 7536 bytes .../lld/test/elf/Inputs/stripped-empty.x86_64 | Bin 0 -> 416 bytes .../lld/test/elf/Inputs/target-test.hexagon | Bin 0 -> 676 bytes .../dist/lld/test/elf/Inputs/target-test.ppc | Bin 0 -> 552 bytes .../bsd/llvm/dist/lld/test/elf/Inputs/tls.S | 50 + .../bsd/llvm/dist/lld/test/elf/Inputs/tls.c | 11 + .../llvm/dist/lld/test/elf/Inputs/tls.x86-64 | Bin 0 -> 1424 bytes .../dist/lld/test/elf/Inputs/tlsAddr.x86-64 | Bin 0 -> 1752 bytes .../llvm/dist/lld/test/elf/Inputs/tlsaddr.c | 8 + .../lld/test/elf/Inputs/undef-from-main-so.c | 1 + .../lld/test/elf/Inputs/undef-from-main.c | 5 + .../dist/lld/test/elf/Inputs/use-shared-32s.c | 8 + .../lld/test/elf/Inputs/use-shared-32s.x86-64 | Bin 0 -> 1336 bytes .../dist/lld/test/elf/Inputs/use-shared.c | 7 + .../lld/test/elf/Inputs/use-shared.x86-64 | Bin 0 -> 1376 bytes .../dist/lld/test/elf/Inputs/x86-64-relocs.S | 12 + .../lld/test/elf/X86_64/Inputs/constint.c | 1 + .../dist/lld/test/elf/X86_64/Inputs/debug0.c | 5 + .../lld/test/elf/X86_64/Inputs/debug0.x86-64 | Bin 0 -> 2704 bytes .../dist/lld/test/elf/X86_64/Inputs/debug1.c | 3 + .../lld/test/elf/X86_64/Inputs/debug1.x86-64 | Bin 0 -> 2584 bytes .../lld/test/elf/X86_64/Inputs/externtls.c | 6 + .../test/elf/X86_64/Inputs/externtls.x86-64 | Bin 0 -> 1424 bytes .../llvm/dist/lld/test/elf/X86_64/Inputs/fn.c | 4 + .../dist/lld/test/elf/X86_64/Inputs/group/1.c | 8 + .../lld/test/elf/X86_64/Inputs/group/fn.c | 4 + .../lld/test/elf/X86_64/Inputs/group/fn1.c | 3 + .../lld/test/elf/X86_64/Inputs/group/fn2.c | 3 + .../lld/test/elf/X86_64/Inputs/group/group.sh | 37 + .../test/elf/X86_64/Inputs/initfini-option.c | 13 + .../lld/test/elf/X86_64/Inputs/initfini.c | 14 + .../lld/test/elf/X86_64/Inputs/largebss.c | 3 + .../lld/test/elf/X86_64/Inputs/layoutpass/1.c | 8 + .../lld/test/elf/X86_64/Inputs/layoutpass/2.c | 7 + .../lld/test/elf/X86_64/Inputs/layoutpass/3.c | 3 + .../dist/lld/test/elf/X86_64/Inputs/main.c | 4 + .../lld/test/elf/X86_64/Inputs/multi-ovrd.c | 10 + .../lld/test/elf/X86_64/Inputs/multi-weak.c | 20 + .../dist/lld/test/elf/X86_64/Inputs/nmagic.c | 8 + .../elf/X86_64/Inputs/no-interp-section.c | 1 + .../dist/lld/test/elf/X86_64/Inputs/note.s | 11 + .../lld/test/elf/X86_64/Inputs/note_ro_rw.s | 21 + .../dist/lld/test/elf/X86_64/Inputs/ovrd.c | 6 + .../dist/lld/test/elf/X86_64/Inputs/rodata.c | 3 + .../dist/lld/test/elf/X86_64/Inputs/rodata.s | 24 + .../dist/lld/test/elf/X86_64/Inputs/rwint.c | 1 + .../lld/test/elf/X86_64/Inputs/sectionmap.c | 4 + .../dist/lld/test/elf/X86_64/Inputs/weak.c | 14 + .../dist/lld/test/elf/X86_64/Inputs/weak.s | 21 + .../test/elf/X86_64/Inputs/zerosizedsection.s | 3 + .../llvm/dist/lld/test/elf/X86_64/debug.test | 57 + .../X86_64/dontignorezerosize-sections.test | 9 + .../elf/X86_64/dynlib-nointerp-section.test | 4 + .../lld/test/elf/X86_64/dynlib-search.test | 6 + .../dist/lld/test/elf/X86_64/extern-tls.test | 16 + .../test/elf/X86_64/initfini-alignment.test | 12 + .../lld/test/elf/X86_64/initfini-option.test | 21 + .../lld/test/elf/X86_64/initfini-order.test | 10 + .../dist/lld/test/elf/X86_64/initfini.test | 23 + .../dist/lld/test/elf/X86_64/largebss.test | 20 + .../lld/test/elf/X86_64/layoutpass-order.test | 14 + .../test/elf/X86_64/multi-weak-layout.test | 46 + .../test/elf/X86_64/multi-weak-override.test | 16 + .../elf/X86_64/multi-weak-syms-order.test | 13 + .../llvm/dist/lld/test/elf/X86_64/nmagic.test | 91 ++ .../elf/X86_64/note-sections-ro_plus_rw.test | 42 + .../lld/test/elf/X86_64/note-sections.test | 23 + .../llvm/dist/lld/test/elf/X86_64/omagic.test | 237 +++ .../elf/X86_64/orderatoms-by-override.test | 8 + .../llvm/dist/lld/test/elf/X86_64/rodata.test | 9 + .../lld/test/elf/X86_64/sectionchoice.test | 7 + .../dist/lld/test/elf/X86_64/sectionmap.test | 22 + .../test/elf/X86_64/startGroupEndGroup.test | 41 + .../llvm/dist/lld/test/elf/X86_64/undef.test | 18 + .../lld/test/elf/X86_64/underscore-end.test | 81 + .../lld/test/elf/X86_64/weak-override.test | 54 + .../lld/test/elf/X86_64/weak-zero-sized.test | 31 + .../dist/lld/test/elf/X86_64/yamlinput.test | 166 ++ external/bsd/llvm/dist/lld/test/elf/abs.test | 19 + .../lld/test/elf/archive-elf-forceload.test | 43 + .../llvm/dist/lld/test/elf/archive-elf.test | 36 + .../bsd/llvm/dist/lld/test/elf/branch.test | 34 + .../bsd/llvm/dist/lld/test/elf/check.test | 39 + .../llvm/dist/lld/test/elf/checkrodata.test | 9 + .../bsd/llvm/dist/lld/test/elf/common.test | 10 + .../dist/lld/test/elf/dynamic-segorder.test | 16 + .../llvm/dist/lld/test/elf/dynamic-undef.test | 29 + .../bsd/llvm/dist/lld/test/elf/dynamic.test | 82 + .../llvm/dist/lld/test/elf/eh_frame_hdr.test | 26 + .../bsd/llvm/dist/lld/test/elf/entry.objtxt | 58 + .../bsd/llvm/dist/lld/test/elf/gotpcrel.test | 22 + .../lld/test/elf/hexagon-quickdata-sort.test | 12 + .../elf/hexagon-quickdata-sortcommon.test | 16 + .../bsd/llvm/dist/lld/test/elf/ifunc.test | 69 + .../dist/lld/test/elf/init_array-order.test | 37 + .../llvm/dist/lld/test/elf/init_array.test | 6 + .../dist/lld/test/elf/librarynotfound.test | 5 + .../test/elf/linkerscript/Inputs/invalid.ls | 1 + .../lld/test/elf/linkerscript/invalid.test | 5 + .../llvm/dist/lld/test/elf/mergeatoms.test | 6 + .../dist/lld/test/elf/mergeconstants.test | 23 + .../dist/lld/test/elf/mergeglobalatoms.test | 11 + .../lld/test/elf/options/dynamic-linker.test | 17 + external/bsd/llvm/dist/lld/test/elf/phdr.test | 99 ++ external/bsd/llvm/dist/lld/test/elf/ppc.test | 14 + .../bsd/llvm/dist/lld/test/elf/quickdata.test | 15 + .../bsd/llvm/dist/lld/test/elf/reloc.test | 41 + .../bsd/llvm/dist/lld/test/elf/rodata.test | 5 + .../bsd/llvm/dist/lld/test/elf/roundtrip.test | 11 + .../bsd/llvm/dist/lld/test/elf/sections.test | 142 ++ .../bsd/llvm/dist/lld/test/elf/soname.test | 6 + .../dist/lld/test/elf/stripped-empty.test | 3 + .../bsd/llvm/dist/lld/test/elf/symbols.test | 33 + external/bsd/llvm/dist/lld/test/elf/tls.test | 42 + .../bsd/llvm/dist/lld/test/elf/tlsAddr.test | 7 + .../lld/test/elf/undef-from-main-dso.test | 44 + .../bsd/llvm/dist/lld/test/elf/weaksym.test | 7 + .../lld/test/elf/x86-64-dynamic-relocs.test | 26 + .../dist/lld/test/elf/x86-64-dynamic.test | 81 + external/bsd/llvm/dist/lld/test/elf/x86.test | 38 + .../llvm/dist/lld/test/elf/x86_64-kinds.test | 21 + .../bsd/llvm/dist/lld/test/linker-script.test | 30 + external/bsd/llvm/dist/lld/test/lit.cfg | 142 ++ .../bsd/llvm/dist/lld/test/lit.site.cfg.in | 22 + .../lld/test/pecoff/Inputs/alignment.obj.yaml | 63 + .../llvm/dist/lld/test/pecoff/Inputs/bss.asm | 20 + .../llvm/dist/lld/test/pecoff/Inputs/bss.obj | Bin 0 -> 683 bytes .../lld/test/pecoff/Inputs/comdat.obj.yaml | 43 + .../test/pecoff/Inputs/common-symbol.obj.yaml | 43 + .../lld/test/pecoff/Inputs/drectve.obj.yaml | 65 + .../test/pecoff/Inputs/grouped-sections.asm | 18 + .../pecoff/Inputs/grouped-sections.obj.yaml | 67 + .../dist/lld/test/pecoff/Inputs/hello.asm | 24 + .../lld/test/pecoff/Inputs/hello.obj.yaml | 108 ++ .../lld/test/pecoff/Inputs/imagebase.obj.yaml | 47 + .../dist/lld/test/pecoff/Inputs/main.obj.yaml | 74 + .../llvm/dist/lld/test/pecoff/Inputs/nop.asm | 9 + .../dist/lld/test/pecoff/Inputs/nop.obj.yaml | 55 + .../lld/test/pecoff/Inputs/reloc.obj.yaml | 53 + .../dist/lld/test/pecoff/Inputs/resource.rc | 4 + .../dist/lld/test/pecoff/Inputs/resource.res | Bin 0 -> 108 bytes .../test/pecoff/Inputs/static-data1.obj.yaml | 55 + .../test/pecoff/Inputs/static-data2.obj.yaml | 55 + .../dist/lld/test/pecoff/Inputs/static.lib | Bin 0 -> 1120 bytes .../pecoff/Inputs/unknown-drectve.obj.yaml | 34 + .../dist/lld/test/pecoff/Inputs/vars-main.c | 7 + .../lld/test/pecoff/Inputs/vars-main.obj.yaml | 53 + .../llvm/dist/lld/test/pecoff/Inputs/vars.c | 20 + .../dist/lld/test/pecoff/Inputs/vars.dll.yaml | 19 + .../llvm/dist/lld/test/pecoff/Inputs/vars.lib | Bin 0 -> 1994 bytes .../lld/test/pecoff/Inputs/weak-externals.asm | 25 + .../pecoff/Inputs/weak-externals.obj.yaml | 81 + .../llvm/dist/lld/test/pecoff/alignment.test | 10 + .../llvm/dist/lld/test/pecoff/base-reloc.test | 49 + .../llvm/dist/lld/test/pecoff/baseaddr.test | 17 + .../dist/lld/test/pecoff/bss-section.test | 20 + .../bsd/llvm/dist/lld/test/pecoff/comdat.test | 12 + .../dist/lld/test/pecoff/common-symbol.test | 22 + .../llvm/dist/lld/test/pecoff/dosstub.test | 10 + .../llvm/dist/lld/test/pecoff/drectve.test | 24 + .../llvm/dist/lld/test/pecoff/dynamic.test | 10 + .../dist/lld/test/pecoff/dynamicbase.test | 23 + .../bsd/llvm/dist/lld/test/pecoff/entry.test | 9 + .../lld/test/pecoff/grouped-sections.test | 17 + .../bsd/llvm/dist/lld/test/pecoff/hello.test | 54 + .../bsd/llvm/dist/lld/test/pecoff/help.test | 4 + .../llvm/dist/lld/test/pecoff/imagebase.test | 13 + .../llvm/dist/lld/test/pecoff/importlib.test | 38 + .../llvm/dist/lld/test/pecoff/include.test | 8 + .../bsd/llvm/dist/lld/test/pecoff/lib.test | 12 + .../llvm/dist/lld/test/pecoff/manifest.test | 54 + .../bsd/llvm/dist/lld/test/pecoff/multi.test | 14 + .../llvm/dist/lld/test/pecoff/options.test | 27 + .../bsd/llvm/dist/lld/test/pecoff/reloc.test | 40 + .../llvm/dist/lld/test/pecoff/resource.test | 9 + .../llvm/dist/lld/test/pecoff/trivial.test | 84 ++ .../dist/lld/test/pecoff/unknown-drectve.test | 6 + .../dist/lld/test/pecoff/weak-external.test | 9 + .../bsd/llvm/dist/lld/tools/CMakeLists.txt | 1 + .../llvm/dist/lld/tools/lld/CMakeLists.txt | 10 + external/bsd/llvm/dist/lld/tools/lld/TODO.txt | 51 + external/bsd/llvm/dist/lld/tools/lld/lld.cpp | 37 + .../llvm/dist/lld/unittests/CMakeLists.txt | 15 + .../lld/unittests/CoreTests/CMakeLists.txt | 4 + .../lld/unittests/CoreTests/ParallelTest.cpp | 33 + .../lld/unittests/CoreTests/RangeTest.cpp | 245 +++ .../lld/unittests/DriverTests/CMakeLists.txt | 10 + .../DriverTests/DarwinLdDriverTest.cpp | 234 +++ .../lld/unittests/DriverTests/DriverTest.h | 62 + .../unittests/DriverTests/GnuLdDriverTest.cpp | 56 + .../DriverTests/UniversalDriverTest.cpp | 35 + .../DriverTests/WinLinkDriverTest.cpp | 552 +++++++ .../lld/unittests/MachOTests/CMakeLists.txt | 11 + .../MachONormalizedFileBinaryReaderTests.cpp | 714 +++++++++ .../MachONormalizedFileBinaryWriterTests.cpp | 699 +++++++++ .../MachONormalizedFileYAMLTests.cpp | 769 ++++++++++ .../bsd/llvm/dist/lld/utils/CMakeLists.txt | 1 + .../bsd/llvm/dist/lld/utils/astyle-options | 7 + .../utils/linker-script-test/CMakeLists.txt | 8 + .../linker-script-test/linker-script-test.cpp | 55 + 502 files changed, 47248 insertions(+) create mode 100644 external/bsd/llvm/dist/lld/.arcconfig create mode 100644 external/bsd/llvm/dist/lld/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/LICENSE.TXT create mode 100644 external/bsd/llvm/dist/lld/README.md create mode 100644 external/bsd/llvm/dist/lld/cmake/modules/FindVTune.cmake create mode 100644 external/bsd/llvm/dist/lld/docs/C++11.rst create mode 100644 external/bsd/llvm/dist/lld/docs/Driver.rst create mode 100644 external/bsd/llvm/dist/lld/docs/Makefile create mode 100644 external/bsd/llvm/dist/lld/docs/README.txt create mode 100644 external/bsd/llvm/dist/lld/docs/Readers.rst create mode 100644 external/bsd/llvm/dist/lld/docs/_static/favicon.ico create mode 100644 external/bsd/llvm/dist/lld/docs/_templates/indexsidebar.html create mode 100644 external/bsd/llvm/dist/lld/docs/_templates/layout.html create mode 100644 external/bsd/llvm/dist/lld/docs/conf.py create mode 100644 external/bsd/llvm/dist/lld/docs/design.rst create mode 100644 external/bsd/llvm/dist/lld/docs/development.rst create mode 100644 external/bsd/llvm/dist/lld/docs/getting_started.rst create mode 100644 external/bsd/llvm/dist/lld/docs/hello.png create mode 100644 external/bsd/llvm/dist/lld/docs/index.rst create mode 100644 external/bsd/llvm/dist/lld/docs/llvm-theme/layout.html create mode 100644 external/bsd/llvm/dist/lld/docs/llvm-theme/static/contents.png create mode 100644 external/bsd/llvm/dist/lld/docs/llvm-theme/static/llvm.css create mode 100644 external/bsd/llvm/dist/lld/docs/llvm-theme/static/logo.png create mode 100644 external/bsd/llvm/dist/lld/docs/llvm-theme/static/navigation.png create mode 100644 external/bsd/llvm/dist/lld/docs/llvm-theme/theme.conf create mode 100644 external/bsd/llvm/dist/lld/docs/make.bat create mode 100644 external/bsd/llvm/dist/lld/docs/open_projects.rst create mode 100644 external/bsd/llvm/dist/lld/docs/sphinx_intro.rst create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/AbsoluteAtom.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/ArchiveLibraryFile.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Atom.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/DefinedAtom.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Error.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/File.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/InputGraph.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Instrumentation.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/LLVM.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/LinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Parallel.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Pass.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/PassManager.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Reference.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/Resolver.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/STDExtras.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryAtom.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryFile.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/SymbolTable.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/TODO.txt create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/UndefinedAtom.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Core/range.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Driver/CoreInputGraph.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Driver/DarwinInputGraph.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Driver/Driver.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Driver/GnuLdInputGraph.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Driver/WinLinkInputGraph.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Passes/LayoutPass.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripNativePass.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripYAMLPass.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/AtomLayout.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/CoreLinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ELFLinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/FileArchive.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/LinkerScript.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOFormat.hpp create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOLinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Reader.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ReaderLinkerScript.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/RelocationHelperFunctions.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Simple.h create mode 100644 external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Writer.h create mode 100644 external/bsd/llvm/dist/lld/lib/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/Core/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/Core/DefinedAtom.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/Error.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/File.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/InputGraph.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/LinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/PassManager.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/Resolver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/SymbolTable.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Core/TODO.txt create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/CoreDriver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/CoreOptions.td create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/DarwinLdDriver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/DarwinLdOptions.td create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/Driver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/GnuLdDriver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/GnuLdOptions.td create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/UniversalDriver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/UniversalDriverOptions.td create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/WinLinkDriver.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Driver/WinLinkOptions.td create mode 100644 external/bsd/llvm/dist/lld/lib/Passes/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/Passes/GOTPass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Passes/LayoutPass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Passes/RoundTripNativePass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Passes/RoundTripYAMLPass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/Passes/StubsPass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/CoreLinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/ArrayOrderPass.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Atoms.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Chunk.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/CreateELF.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/DefaultLayout.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/DynamicFile.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/DynamicLibraryWriter.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/ExecutableWriter.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/File.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/HeaderChunks.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTarget.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Hexagon/HexagonV4Encodings.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Layout.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/OutputELFWriter.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/PPC/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/PPC/PPCTarget.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Reader.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/SectionChunks.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/SegmentChunks.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/TODO.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/TargetHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/TargetLayout.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Targets.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Writer.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/Writer.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86/X86LinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86/X86Target.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86/X86TargetHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64Target.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/LinkerScript.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/GOTPass.hpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/ReferenceKinds.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/StubAtoms.hpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/StubsPass.hpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/MachO/WriterMachO.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/Native/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/Native/NativeFileFormat.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/Native/ReaderNative.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/Native/WriterNative.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/Atoms.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/IdataPass.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/ReaderImportHeader.h create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/Reader.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/ReaderLinkerScript.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/Writer.cpp create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/YAML/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp create mode 100644 external/bsd/llvm/dist/lld/test/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/test/Driver/lib-search.test create mode 100644 external/bsd/llvm/dist/lld/test/Driver/libsearch-inputGraph.test create mode 100644 external/bsd/llvm/dist/lld/test/Driver/trivial-driver.test create mode 100644 external/bsd/llvm/dist/lld/test/Driver/undef-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/Unit/lit.cfg create mode 100644 external/bsd/llvm/dist/lld/test/Unit/lit.site.cfg.in create mode 100644 external/bsd/llvm/dist/lld/test/core/absolute-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/absolute-local.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/archive-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/archive-chain.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/archive-tentdef-search.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/auto-hide-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/constants-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/cstring-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/custom-section.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/dead-strip-attributes.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/dead-strip-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/dead-strip-globals.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/empty.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-atom-attribute.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-atom-content-byte-value.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-atom-content-bytes.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-atom-type.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-atom-undefined-wrong-attribue.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-duplicate-absolutes.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-file-attribute.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-fixup-attribute.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/error-fixup-target.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/fixups-addend.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/fixups-dup-named.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/fixups-named.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/fixups-unnamed.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/ingroup-test-big.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/ingroup-test-loop.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/ingroup-test-with-layout-after.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/ingroup-test.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/inline-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/layout-error-test.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/layout-transitivity.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/layoutafter-test.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/layoutbefore-test.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/multiple-def-error.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/pass-got-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/pass-stubs-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/permissions.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/section-position.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/shared-library-basic.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/shared-library-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/tent-merge.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/undef-coalesce-error.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/undef-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/undef-fallback.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/undef-weak-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/core/weak-coalesce.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/darwin/hello-world.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/Inputs/dynobj-data.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/Inputs/dynobj.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/Inputs/got-plt-order.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/Inputs/initfini-option.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/Inputs/use-shared.hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/dynlib-data.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/dynlib-gotoff.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/dynlib-hash.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/dynlib-syms.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/dynlib.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/hexagon-got-plt-order.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/hexagon-plt-setup.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/initfini-option.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/maxalignment.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/rela-order.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Hexagon/sda-base.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/abs-test.i386 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/bar.o.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/branch-test.hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/branch-test.ppc create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/constants-merge.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/constdata.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/foo.o.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/globalconst.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/globalconst.o.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/gotpcrel.S create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/gotpcrel.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/ifunc.S create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/ifunc.cpp create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/ifunc.cpp.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/ifunc.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/init_array.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/mainobj.x86_64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/object-test.elf-hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/object-test.elf-i386 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/phdr.i386 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/quickdata-sortcommon-test.o.elf-hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/quickdata-test.elf-hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/reloc-test.elf-i386 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/reloc-xb.x86 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/reloc-xt.x86 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/relocs-dynamic.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/relocs.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/rodata-test.hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/rodata-test.i386 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/section-test.i386 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/shared.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/shared.so-x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/stripped-empty.x86_64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/target-test.hexagon create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/target-test.ppc create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/tls.S create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/tls.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/tls.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/tlsAddr.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/tlsaddr.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/undef-from-main-so.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/undef-from-main.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/use-shared-32s.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/use-shared-32s.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/use-shared.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/use-shared.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/Inputs/x86-64-relocs.S create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/constint.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/debug0.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/debug0.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/debug1.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/debug1.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/externtls.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/externtls.x86-64 create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/fn.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/group/1.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/group/fn.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/group/fn1.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/group/fn2.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/group/group.sh create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/initfini-option.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/initfini.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/largebss.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/layoutpass/1.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/layoutpass/2.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/layoutpass/3.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/main.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/multi-ovrd.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/multi-weak.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/nmagic.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/no-interp-section.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/note.s create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/note_ro_rw.s create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/ovrd.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/rodata.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/rodata.s create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/rwint.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/sectionmap.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/weak.c create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/weak.s create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/Inputs/zerosizedsection.s create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/debug.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/dontignorezerosize-sections.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/dynlib-nointerp-section.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/dynlib-search.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/extern-tls.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/initfini-alignment.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/initfini-option.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/initfini-order.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/initfini.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/largebss.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/layoutpass-order.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/multi-weak-layout.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/multi-weak-override.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/multi-weak-syms-order.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/nmagic.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/note-sections-ro_plus_rw.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/note-sections.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/omagic.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/orderatoms-by-override.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/rodata.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/sectionchoice.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/sectionmap.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/startGroupEndGroup.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/undef.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/underscore-end.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/weak-override.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/weak-zero-sized.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/X86_64/yamlinput.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/abs.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/archive-elf-forceload.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/archive-elf.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/branch.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/check.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/checkrodata.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/common.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/dynamic-segorder.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/dynamic-undef.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/dynamic.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/eh_frame_hdr.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/entry.objtxt create mode 100644 external/bsd/llvm/dist/lld/test/elf/gotpcrel.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/hexagon-quickdata-sort.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/hexagon-quickdata-sortcommon.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/ifunc.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/init_array-order.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/init_array.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/librarynotfound.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/linkerscript/Inputs/invalid.ls create mode 100644 external/bsd/llvm/dist/lld/test/elf/linkerscript/invalid.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/mergeatoms.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/mergeconstants.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/mergeglobalatoms.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/options/dynamic-linker.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/phdr.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/ppc.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/quickdata.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/reloc.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/rodata.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/roundtrip.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/sections.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/soname.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/stripped-empty.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/symbols.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/tls.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/tlsAddr.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/undef-from-main-dso.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/weaksym.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/x86-64-dynamic-relocs.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/x86-64-dynamic.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/x86.test create mode 100644 external/bsd/llvm/dist/lld/test/elf/x86_64-kinds.test create mode 100644 external/bsd/llvm/dist/lld/test/linker-script.test create mode 100644 external/bsd/llvm/dist/lld/test/lit.cfg create mode 100644 external/bsd/llvm/dist/lld/test/lit.site.cfg.in create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/alignment.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/bss.asm create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/bss.obj create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/comdat.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/common-symbol.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/drectve.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/grouped-sections.asm create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/grouped-sections.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/hello.asm create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/hello.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/imagebase.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/main.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/nop.asm create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/nop.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/reloc.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/resource.rc create mode 100755 external/bsd/llvm/dist/lld/test/pecoff/Inputs/resource.res create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/static-data1.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/static-data2.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/static.lib create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/unknown-drectve.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/vars-main.c create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/vars-main.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/vars.c create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/vars.dll.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/vars.lib create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/weak-externals.asm create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/Inputs/weak-externals.obj.yaml create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/alignment.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/base-reloc.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/baseaddr.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/bss-section.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/comdat.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/common-symbol.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/dosstub.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/drectve.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/dynamic.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/dynamicbase.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/entry.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/grouped-sections.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/hello.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/help.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/imagebase.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/importlib.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/include.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/lib.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/manifest.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/multi.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/options.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/reloc.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/resource.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/trivial.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/unknown-drectve.test create mode 100644 external/bsd/llvm/dist/lld/test/pecoff/weak-external.test create mode 100644 external/bsd/llvm/dist/lld/tools/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/tools/lld/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/tools/lld/TODO.txt create mode 100644 external/bsd/llvm/dist/lld/tools/lld/lld.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/unittests/CoreTests/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/unittests/CoreTests/ParallelTest.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/CoreTests/RangeTest.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/DriverTests/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/unittests/DriverTests/DarwinLdDriverTest.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/DriverTests/DriverTest.h create mode 100644 external/bsd/llvm/dist/lld/unittests/DriverTests/GnuLdDriverTest.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/DriverTests/UniversalDriverTest.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/DriverTests/WinLinkDriverTest.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/MachOTests/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp create mode 100644 external/bsd/llvm/dist/lld/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp create mode 100644 external/bsd/llvm/dist/lld/utils/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/utils/astyle-options create mode 100644 external/bsd/llvm/dist/lld/utils/linker-script-test/CMakeLists.txt create mode 100644 external/bsd/llvm/dist/lld/utils/linker-script-test/linker-script-test.cpp diff --git a/external/bsd/llvm/dist/lld/.arcconfig b/external/bsd/llvm/dist/lld/.arcconfig new file mode 100644 index 000000000..c9d66b278 --- /dev/null +++ b/external/bsd/llvm/dist/lld/.arcconfig @@ -0,0 +1,4 @@ +{ + "project_id" : "lld", + "conduit_uri" : "http://llvm-reviews.chandlerc.com/" +} diff --git a/external/bsd/llvm/dist/lld/CMakeLists.txt b/external/bsd/llvm/dist/lld/CMakeLists.txt new file mode 100644 index 000000000..22f50c9f4 --- /dev/null +++ b/external/bsd/llvm/dist/lld/CMakeLists.txt @@ -0,0 +1,169 @@ +# If we are not building as a part of LLVM, build lld as a standalone project, +# using LLVM as an external library. + + + +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project(lld) + cmake_minimum_required(VERSION 2.8) + + set(LLD_PATH_TO_LLVM_SOURCE "" CACHE PATH + "Path to LLVM source code. Not necessary if using an installed LLVM.") + set(LLD_PATH_TO_LLVM_BUILD "" CACHE PATH + "Path to the directory where LLVM was built or installed.") + + if (LLD_PATH_TO_LLVM_SOURCE) + if (NOT EXISTS "${LLD_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake") + message(FATAL_ERROR "Please set LLD_PATH_TO_LLVM_SOURCE to the root " + "directory of LLVM source code.") + else() + get_filename_component(LLVM_MAIN_SRC_DIR ${LLD_PATH_TO_LLVM_SOURCE} + ABSOLUTE) + list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") + endif() + endif() + + list(APPEND CMAKE_MODULE_PATH "${LLD_PATH_TO_LLVM_BUILD}/share/llvm/cmake") + + get_filename_component(PATH_TO_LLVM_BUILD ${LLD_PATH_TO_LLVM_BUILD} + ABSOLUTE) + + option(LLVM_INSTALL_TOOLCHAIN_ONLY + "Only include toolchain files in the 'install' target." OFF) + + include(AddLLVM) + include(TableGen) + include("${LLD_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake") + include(HandleLLVMOptions) + + set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}") + + set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include") + set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR}) + + set(CMAKE_INCLUDE_CURRENT_DIR ON) + include_directories("${PATH_TO_LLVM_BUILD}/include" + "${LLVM_MAIN_INCLUDE_DIR}") + link_directories("${PATH_TO_LLVM_BUILD}/lib") + + if (EXISTS "${LLD_PATH_TO_LLVM_BUILD}/bin/llvm-config${CMAKE_EXECUTABLE_SUFFIX}") + set (PATH_TO_LLVM_CONFIG "${LLD_PATH_TO_LLVM_BUILD}/bin/llvm-config${CMAKE_EXECUTABLE_SUFFIX}") + elseif (EXISTS "${LLD_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-config${CMAKE_EXECUTABLE_SUFFIX}") + # FIXME: This is an utter hack. + set (PATH_TO_LLVM_CONFIG "${LLD_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-config${CMAKE_EXECUTABLE_SUFFIX}") + else() + message(FATAL_ERROR "Please set LLD_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.") + endif() + + exec_program("${PATH_TO_LLVM_CONFIG} --bindir" OUTPUT_VARIABLE LLVM_BINARY_DIR) + set(LLVM_TABLEGEN_EXE "${LLVM_BINARY_DIR}/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}") + + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + + set(LLD_BUILT_STANDALONE 1) +endif() + +set(LLD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(LLD_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite " +"the makefiles distributed with LLVM. Please create a directory and run cmake " +"from there, passing the path to this source directory as the last argument. " +"This process created the file `CMakeCache.txt' and the directory " +"`CMakeFiles'. Please delete them.") +endif() + +list (APPEND CMAKE_MODULE_PATH "${LLD_SOURCE_DIR}/cmake/modules") + +option(LLD_USE_VTUNE + "Enable VTune user task tracking." + OFF) +if (LLD_USE_VTUNE) + find_package(VTune) + if (VTUNE_FOUND) + include_directories(${VTune_INCLUDE_DIRS}) + list(APPEND LLVM_COMMON_LIBS ${VTune_LIBRARIES}) + add_definitions(-DLLD_HAS_VTUNE) + endif() +endif() + +# lld requires c++11 to build. Make sure that we have a compiler and standard +# library combination that can do that. +if (NOT MSVC) + # gcc and clang require the -std=c++0x or -std=c++11 flag. + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang" AND + NOT ("${CMAKE_CXX_FLAGS}" MATCHES ".*-std=(c|gnu)\\+\\+(0x|11).*")) + message(FATAL_ERROR + "lld requires c++11. Clang and gcc require -std=c++0x or -std=c++11 to " + "enter this mode. Please set CMAKE_CXX_FLAGS accordingly.") + endif() +elseif (MSVC_VERSION LESS 1700) + message(FATAL_ERROR "The selected compiler does not support c++11 which is " + "required to build lld.") +endif() + +macro(add_lld_library name) + llvm_process_sources(srcs ${ARGN}) + if (MSVC_IDE OR XCODE) + string(REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR}) + list(GET split_path -1 dir) + file(GLOB_RECURSE headers + ../../include/lld${dir}/*.h) + set(srcs ${srcs} ${headers}) + endif() + if (MODULE) + set(libkind MODULE) + elseif (SHARED_LIBRARY) + set(libkind SHARED) + else() + set(libkind) + endif() + add_library(${name} ${libkind} ${srcs}) + if (LLVM_COMMON_DEPENDS) + add_dependencies(${name} ${LLVM_COMMON_DEPENDS}) + endif() + + target_link_libraries(${name} ${LLVM_USED_LIBS}) + llvm_config(${name} ${LLVM_LINK_COMPONENTS}) + target_link_libraries(${name} ${LLVM_COMMON_LIBS}) + link_system_libs(${name}) + + if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) + install(TARGETS ${name} + LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) + endif() + set_target_properties(${name} PROPERTIES FOLDER "lld libraries") +endmacro(add_lld_library) + +macro(add_lld_executable name) + add_llvm_executable(${name} ${ARGN}) + set_target_properties(${name} PROPERTIES FOLDER "lld executables") +endmacro(add_lld_executable) + +include_directories(BEFORE + ${CMAKE_CURRENT_BINARY_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) + install(DIRECTORY include/ + DESTINATION include + FILES_MATCHING + PATTERN "*.h" + PATTERN ".svn" EXCLUDE + ) +endif() + +add_subdirectory(lib) +add_subdirectory(tools) +add_subdirectory(utils) + +add_subdirectory(test) + +if (LLVM_INCLUDE_TESTS AND NOT LLD_BUILT_STANDALONE) + add_subdirectory(unittests) +endif() diff --git a/external/bsd/llvm/dist/lld/LICENSE.TXT b/external/bsd/llvm/dist/lld/LICENSE.TXT new file mode 100644 index 000000000..0a2b5b7c7 --- /dev/null +++ b/external/bsd/llvm/dist/lld/LICENSE.TXT @@ -0,0 +1,62 @@ +============================================================================== +lld License +============================================================================== +University of Illinois/NCSA +Open Source License + +Copyright (c) 2011-2013 by the contributors listed in CREDITS.TXT +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== +The lld software contains code written by third parties. Such software will +have its own individual LICENSE.TXT file in the directory in which it appears. +This file will describe the copyrights, license, and restrictions which apply +to that code. + +The disclaimer of warranty in the University of Illinois Open Source License +applies to all code in the lld Distribution, and nothing in any of the +other licenses gives permission to use the names of the LLVM Team or the +University of Illinois to endorse or promote products derived from this +Software. + +The following pieces of software have additional or alternate copyrights, +licenses, and/or restrictions: + +Program Directory +------- --------- + diff --git a/external/bsd/llvm/dist/lld/README.md b/external/bsd/llvm/dist/lld/README.md new file mode 100644 index 000000000..dc05cdea0 --- /dev/null +++ b/external/bsd/llvm/dist/lld/README.md @@ -0,0 +1,10 @@ + +LLVM Linker (lld) +============================== + +This directory and its subdirectories contain source code for the LLVM Linker, a +modular cross platform linker which is built as part of the LLVM compiler +infrastructure project. + +lld is open source software. You may freely distribute it under the terms of +the license agreement found in LICENSE.txt. diff --git a/external/bsd/llvm/dist/lld/cmake/modules/FindVTune.cmake b/external/bsd/llvm/dist/lld/cmake/modules/FindVTune.cmake new file mode 100644 index 000000000..bd0cbe9a3 --- /dev/null +++ b/external/bsd/llvm/dist/lld/cmake/modules/FindVTune.cmake @@ -0,0 +1,31 @@ +# - Find VTune ittnotify. +# Defines: +# VTune_FOUND +# VTune_INCLUDE_DIRS +# VTune_LIBRARIES + +set(dirs + "$ENV{VTUNE_AMPLIFIER_XE_2013_DIR}/" + "C:/Program Files (x86)/Intel/VTune Amplifier XE 2013/" + "$ENV{VTUNE_AMPLIFIER_XE_2011_DIR}/" + "C:/Program Files (x86)/Intel/VTune Amplifier XE 2011/" + ) + +find_path(VTune_INCLUDE_DIRS ittnotify.h + PATHS ${dirs} + PATH_SUFFIXES include) + +if (CMAKE_SIZEOF_VOID_P MATCHES "8") + set(vtune_lib_dir lib64) +else() + set(vtune_lib_dir lib32) +endif() + +find_library(VTune_LIBRARIES libittnotify + HINTS "${VTune_INCLUDE_DIRS}/.." + PATHS ${dirs} + PATH_SUFFIXES ${vtune_lib_dir}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + VTune DEFAULT_MSG VTune_LIBRARIES VTune_INCLUDE_DIRS) diff --git a/external/bsd/llvm/dist/lld/docs/C++11.rst b/external/bsd/llvm/dist/lld/docs/C++11.rst new file mode 100644 index 000000000..e47a030eb --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/C++11.rst @@ -0,0 +1,35 @@ +C++11 +===== + +lld is developed in a limited subset of C++11. Supported compilers are: + +* Clang 3.1+ +* g++ 4.6+ +* MSVC 2012+ + +Allowed Features +---------------- + +Allowed features are based on what these compilers support. Features that are ok +to omit (such as final or = delete) may be conditionally used via macros. + +* All of the C++11 standard library, including threading and atomics +* auto +* constexpr via LLVM_CONSTEXPR +* decltype +* deleted functions via LLVM_DELETED_FUNCTION +* Forward enum declarations +* Lambdas +* Local and unnamed types as template args +* Trailing return type +* nullptr +* >> instead of > > +* R-Value references excluding R-Value references for this +* static_assert +* Strongly typed enums +* Range based for loop +* final via LLVM_FINAL + +Note that some of these features may not be fully or correctly implemented in +all compilers. Issues using these features should be added here as they are +encountered. diff --git a/external/bsd/llvm/dist/lld/docs/Driver.rst b/external/bsd/llvm/dist/lld/docs/Driver.rst new file mode 100644 index 000000000..49010ee80 --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/Driver.rst @@ -0,0 +1,79 @@ +====== +Driver +====== + +.. contents:: + :local: + +Introduction +============ + +This document describes the lld driver. The purpose of this document is to +describe both the motivation and design goals for the driver, as well as details +of the internal implementation. + +Overview +======== + +The lld driver is designed to support a number of different command line +interfaces. The main interfaces we plan to support are binutils' ld, Apple's +ld, and Microsoft's link.exe. + +Flavors +------- + +Each of these different interfaces is referred to as a flavor. There is also an +extra flavor "core" which is used to exercise the core functionality of the +linker it the test suite. + +* gnu +* darwin +* link +* core + +Selecting a Flavor +^^^^^^^^^^^^^^^^^^ + +There are two different ways to tell lld which flavor to be. They are checked in +order, so the second overrides the first. The first is to symlink :program:`lld` +as :program:`lld-{flavor}` or just :program:`{flavor}`. You can also specify +it as the first command line argument using ``-flavor``:: + + $ lld -flavor gnu + +There is a shortcut for ``-flavor core`` as ``-core``. + + +Adding an Option to an existing Flavor +====================================== + +#. Add the option to the desired :file:`lib/Driver/{flavor}Options.td`. + +#. Add to :cpp:class:`lld::FlavorLinkingContext` a getter and setter method + for the option. + +#. Modify :cpp:func:`lld::FlavorDriver::parse` in :file: + `lib/Driver/{Flavor}Driver.cpp` to call the targetInfo setter + for corresponding to the option. + +#. Modify {Flavor}Reader and {Flavor}Writer to use the new targtInfo option. + + +Adding a Flavor +=============== + +#. Add an entry for the flavor in :file:`include/lld/Driver/Driver.h` to + :cpp:class:`lld::UniversalDriver::Flavor`. + +#. Add an entry in :file:`lib/Driver/UniversalDriver.cpp` to + :cpp:func:`lld::Driver::strToFlavor` and + :cpp:func:`lld::UniversalDriver::link`. + This allows the flavor to be selected via symlink and :option:`-flavor`. + +#. Add a tablegen file called :file:`lib/Driver/{flavor}Options.td` that + describes the options. If the options are a superset of another driver, that + driver's td file can simply be included. The :file:`{flavor}Options.td` file + must also be added to :file:`lib/Driver/CMakeLists.txt`. + +#. Add a ``{flavor}Driver`` as a subclass of :cpp:class:`lld::Driver` + in :file:`lib/Driver/{flavor}Driver.cpp`. diff --git a/external/bsd/llvm/dist/lld/docs/Makefile b/external/bsd/llvm/dist/lld/docs/Makefile new file mode 100644 index 000000000..4c147eb11 --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/Makefile @@ -0,0 +1,155 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +all: html + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/lld.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/lld.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/lld" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/lld" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/external/bsd/llvm/dist/lld/docs/README.txt b/external/bsd/llvm/dist/lld/docs/README.txt new file mode 100644 index 000000000..eb09a2d2b --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/README.txt @@ -0,0 +1,12 @@ +lld Documentation +================= + +The lld documentation is written using the Sphinx documentation generator. It is +currently tested with Sphinx 1.1.3. + +We currently use the 'nature' theme and a Beaker inspired structure. + +To rebuild documents into html: + + [/lld/docs]> make html + diff --git a/external/bsd/llvm/dist/lld/docs/Readers.rst b/external/bsd/llvm/dist/lld/docs/Readers.rst new file mode 100644 index 000000000..ddda4736f --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/Readers.rst @@ -0,0 +1,172 @@ +.. _Readers: + +Developing lld Readers +====================== + +Introduction +------------ + +The purpose of a "Reader" is to take an object file in a particular format +and create an `lld::File`:cpp:class: (which is a graph of Atoms) +representing the object file. A Reader inherits from +`lld::Reader`:cpp:class: which lives in +:file:`include/lld/ReaderWriter/Reader.h` and +:file:`lib/ReaderWriter/Reader.cpp`. + +The Reader infrastructure for an object format ``Foo`` requires the +following pieces in order to fit into lld: + +:file:`include/lld/ReaderWriter/ReaderFoo.h` + + .. cpp:class:: ReaderOptionsFoo : public ReaderOptions + + This Options class is the only way to configure how the Reader will + parse any file into an `lld::Reader`:cpp:class: object. This class + should be declared in the `lld`:cpp:class: namespace. + + .. cpp:function:: Reader *createReaderFoo(ReaderOptionsFoo &reader) + + This factory function configures and create the Reader. This function + should be declared in the `lld`:cpp:class: namespace. + +:file:`lib/ReaderWriter/Foo/ReaderFoo.cpp` + + .. cpp:class:: ReaderFoo : public Reader + + This is the concrete Reader class which can be called to parse + object files. It should be declared in an anonymous namespace or + if there is shared code with the `lld::WriterFoo`:cpp:class: you + can make a nested namespace (e.g. `lld::foo`:cpp:class:). + +You may have noticed that :cpp:class:`ReaderFoo` is not declared in the +``.h`` file. An important design aspect of lld is that all Readers are +created *only* through an object-format-specific +:cpp:func:`createReaderFoo` factory function. The creation of the Reader is +parametrized through a :cpp:class:`ReaderOptionsFoo` class. This options +class is the one-and-only way to control how the Reader operates when +parsing an input file into an Atom graph. For instance, you may want the +Reader to only accept certain architectures. The options class can be +instantiated from command line options or be programmatically configured. + +Where to start +-------------- + +The lld project already has a skeleton of source code for Readers for +``ELF``, ``PECOFF``, ``MachO``, and lld's native Atom graph format +(both binary ``Native`` and ``YAML`` representations). If your file format +is a variant of one of those, you should modify the existing Reader to +support your variant. This is done by customizing the Options +class for the Reader and making appropriate changes to the ``.cpp`` file to +interpret those options and act accordingly. + +If your object file format is not a variant of any existing Reader, you'll need +to create a new Reader subclass with the organization described above. + +Readers are factories +--------------------- + +The linker will usually only instantiate your Reader once. That one Reader will +have its parseFile() method called many times with different input files. +To support multithreaded linking, the Reader may be parsing multiple input +files in parallel. Therefore, there should be no parsing state in you Reader +object. Any parsing state should be in ivars of your File subclass or in +some temporary object. + +The key method to implement in a reader is:: + + virtual error_code parseFile(LinkerInput &input, + std::vector> &result); + +It takes a memory buffer (which contains the contents of the object file +being read) and returns an instantiated lld::File object which is +a collection of Atoms. The result is a vector of File pointers (instead of +simple a File pointer) because some file formats allow multiple object +"files" to be encoded in one file system file. + + +Memory Ownership +---------------- + +Atoms are always owned by their File object. During core linking when Atoms +are coalesced or stripped away, core linking does not delete them. +Core linking just removes those unused Atoms from its internal list. +The destructor of a File object is responsible for deleting all Atoms it +owns, and if ownership of the MemoryBuffer was passed to it, the File +destructor needs to delete that too. + +Making Atoms +------------ + +The internal model of lld is purely Atom based. But most object files do not +have an explicit concept of Atoms, instead most have "sections". The way +to think of this is that a section is just a list of Atoms with common +attributes. + +The first step in parsing section-based object files is to cleave each +section into a list of Atoms. The technique may vary by section type. For +code sections (e.g. .text), there are usually symbols at the start of each +function. Those symbol addresses are the points at which the section is +cleaved into discrete Atoms. Some file formats (like ELF) also include the +length of each symbol in the symbol table. Otherwise, the length of each +Atom is calculated to run to the start of the next symbol or the end of the +section. + +Other sections types can be implicitly cleaved. For instance c-string literals +or unwind info (e.g. .eh_frame) can be cleaved by having the Reader look at +the content of the section. It is important to cleave sections into Atoms +to remove false dependencies. For instance the .eh_frame section often +has no symbols, but contains "pointers" to the functions for which it +has unwind info. If the .eh_frame section was not cleaved (but left as one +big Atom), there would always be a reference (from the eh_frame Atom) to +each function. So the linker would be unable to coalesce or dead stripped +away the function atoms. + +The lld Atom model also requires that a reference to an undefined symbol be +modeled as a Reference to an UndefinedAtom. So the Reader also needs to +create an UndefinedAtom for each undefined symbol in the object file. + +Once all Atoms have been created, the second step is to create References +(recall that Atoms are "nodes" and References are "edges"). Most References +are created by looking at the "relocation records" in the object file. If +a function contains a call to "malloc", there is usually a relocation record +specifying the address in the section and the symbol table index. Your +Reader will need to convert the address to an Atom and offset and the symbol +table index into a target Atom. If "malloc" is not defined in the object file, +the target Atom of the Reference will be an UndefinedAtom. + + +Performance +----------- +Once you have the above working to parse an object file into Atoms and +References, you'll want to look at performance. Some techniques that can +help performance are: + +* Use llvm::BumpPtrAllocator or pre-allocate one big vector and then + just have each atom point to its subrange of References in that vector. + This can be faster that allocating each Reference as separate object. +* Pre-scan the symbol table and determine how many atoms are in each section + then allocate space for all the Atom objects at once. +* Don't copy symbol names or section content to each Atom, instead use + StringRef and ArrayRef in each Atom to point to its name and content in the + MemoryBuffer. + + +Testing +------- + +We are still working on infrastructure to test Readers. The issue is that +you don't want to check in binary files to the test suite. And the tools +for creating your object file from assembly source may not be available on +every OS. + +We are investigating a way to use YAML to describe the section, symbols, +and content of a file. Then have some code which will write out an object +file from that YAML description. + +Once that is in place, you can write test cases that contain section/symbols +YAML and is run through the linker to produce Atom/References based YAML which +is then run through FileCheck to verify the Atoms and References are as +expected. + + + diff --git a/external/bsd/llvm/dist/lld/docs/_static/favicon.ico b/external/bsd/llvm/dist/lld/docs/_static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..724ad6e12dd406cd595568426b88aedfd46365f9 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYJy!TNEAIg9K{NV?ggU<}0-qQQ`@9I5#a5w7W zg)`m94(*%s?CBHjj~_pXzI*f9osj;&fB!Il`t(u%&!0c+pFe++KX!Qk^7*qS|J}Z6 z&8rvBo@C?G|L*NuS&-X){P@8-d-~MMGpA1aZ(g^0a%OVOx8;lG{NK54!|`w5zHxr} z@|g!{K8ioSfBVKZxvyu=^QTWF!~8r>>Z>XI4fplkMELCAKvr-^ZPf? z*^@`N-Mo6aC??eZueYQ1&0jx%GQ<4S(O5gdR8#qXfUCoQM`PXpQT`r3zJL2FcjfZA z!kZUQy#TtG|LNlgHE-X%vgm7XK5M3_^mopTDfMq&zZL@dB_%rafR(P=|Cj);|6!g^ z|L0DfxCvzTl}i_9e0cvZ1;oC8>-s{VnWEb^tZfI`;c9LA?aayJHXyh8yV~Ef)>HrQ zZe{#GKPB$l`O_!bK>mC4`jzLcYgc9iao>xlkJCZs?BBJ$GQ8MA%AW3HU4kgxIPM| z4rKQC@83j!{rbfT6T?P-2Bwc`y&Wfl+#G*hzIfgRrUs-RgkgMKG)N6FP0M}z_EnM? z^|;KTo;U;0%@F(tNdL13VtEFJ3+xOG2QM=)G#4{4G+hMJmJAI2AA#zABGiNQ0RZmu B;|2f# literal 0 HcmV?d00001 diff --git a/external/bsd/llvm/dist/lld/docs/_templates/indexsidebar.html b/external/bsd/llvm/dist/lld/docs/_templates/indexsidebar.html new file mode 100644 index 000000000..61968f22d --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/_templates/indexsidebar.html @@ -0,0 +1,4 @@ +

Bugs

+ +

lld bugs should be reported at the + LLVM Bugzilla.

diff --git a/external/bsd/llvm/dist/lld/docs/_templates/layout.html b/external/bsd/llvm/dist/lld/docs/_templates/layout.html new file mode 100644 index 000000000..519a24bce --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/_templates/layout.html @@ -0,0 +1,12 @@ +{% extends "!layout.html" %} + +{% block extrahead %} + +{% endblock %} + +{% block rootrellink %} +
  • lld Home | 
  • +{% endblock %} diff --git a/external/bsd/llvm/dist/lld/docs/conf.py b/external/bsd/llvm/dist/lld/docs/conf.py new file mode 100644 index 000000000..2518dad25 --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/conf.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +# +# lld documentation build configuration file. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'lld' +copyright = u'2011-2013, LLVM Project' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '3.2' +# The full version, including alpha/beta/rc tags. +release = '3.2' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +today_fmt = '%Y-%m-%d' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +show_authors = True + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'friendly' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'llvm-theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ["."] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'favicon.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%Y-%m-%d' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +html_sidebars = {'index': 'indexsidebar.html'} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {'index': 'index.html'} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'llddoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('contents', 'lld.tex', u'lld Documentation', + u'LLVM project', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('contents', 'lld', u'lld Documentation', + [u'LLVM project'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('contents', 'lld', u'lld Documentation', + u'LLVM project', 'lld', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# FIXME: Define intersphinx configration. +intersphinx_mapping = {} + + +# -- Options for extensions ---------------------------------------------------- + +# Enable this if you want TODOs to show up in the generated documentation. +todo_include_todos = True diff --git a/external/bsd/llvm/dist/lld/docs/design.rst b/external/bsd/llvm/dist/lld/docs/design.rst new file mode 100644 index 000000000..2a79bd0a4 --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/design.rst @@ -0,0 +1,470 @@ +.. _design: + +Linker Design +============= + +Introduction +------------ + +lld is a new generation of linker. It is not "section" based like traditional +linkers which mostly just interlace sections from multiple object files into the +output file. Instead, lld is based on "Atoms". Traditional section based +linking work well for simple linking, but their model makes advanced linking +features difficult to implement. Features like dead code stripping, reordering +functions for locality, and C++ coalescing require the linker to work at a finer +grain. + +An atom is an indivisible chunk of code or data. An atom has a set of +attributes, such as: name, scope, content-type, alignment, etc. An atom also +has a list of References. A Reference contains: a kind, an optional offset, an +optional addend, and an optional target atom. + +The Atom model allows the linker to use standard graph theory models for linking +data structures. Each atom is a node, and each Reference is an edge. The +feature of dead code stripping is implemented by following edges to mark all +live atoms, and then delete the non-live atoms. + + +Atom Model +---------- + +An atom is an indivisible chunk of code or data. Typically each user written +function or global variable is an atom. In addition, the compiler may emit +other atoms, such as for literal c-strings or floating point constants, or for +runtime data structures like dwarf unwind info or pointers to initializers. + +A simple "hello world" object file would be modeled like this: + +.. image:: hello.png + +There are three atoms: main, a proxy for printf, and an anonymous atom +containing the c-string literal "hello world". The Atom "main" has two +references. One is the call site for the call to printf, and the other is a +reference for the instruction that loads the address of the c-string literal. + +There are only four different types of atoms: + + * DefinedAtom + 95% of all atoms. This is a chunk of code or data + + * UndefinedAtom + This is a place holder in object files for a reference to some atom + outside the translation unit.During core linking it is usually replaced + by (coalesced into) another Atom. + + * SharedLibraryAtom + If a required symbol name turns out to be defined in a dynamic shared + library (and not some object file). A SharedLibraryAtom is the + placeholder Atom used to represent that fact. + + It is similar to an UndefinedAtom, but it also tracks information + about the associated shared library. + + * AbsoluteAtom + This is for embedded support where some stuff is implemented in ROM at + some fixed address. This atom has no content. It is just an address + that the Writer needs to fix up any references to point to. + + +File Model +---------- + +The linker views the input files as basically containers of Atoms and +References, and just a few attributes of their own. The linker works with three +kinds of files: object files, static libraries, and dynamic shared libraries. +Each kind of file has reader object which presents the file in the model +expected by the linker. + +Object File +~~~~~~~~~~~ + +An object file is just a container of atoms. When linking an object file, a +reader is instantiated which parses the object file and instantiates a set of +atoms representing all content in the .o file. The linker adds all those atoms +to a master graph. + +Static Library (Archive) +~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the traditional unix static archive which is just a collection of object +files with a "table of contents". When linking with a static library, by default +nothing is added to the master graph of atoms. Instead, if after merging all +atoms from object files into a master graph, if any "undefined" atoms are left +remaining in the master graph, the linker reads the table of contents for each +static library to see if any have the needed definitions. If so, the set of +atoms from the specified object file in the static library is added to the +master graph of atoms. + +Dynamic Library (Shared Object) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Dynamic libraries are different than object files and static libraries in that +they don't directly add any content. Their purpose is to check at build time +that the remaining undefined references can be resolved at runtime, and provide +a list of dynamic libraries (SO_NEEDED) that will be needed at runtime. The way +this is modeled in the linker is that a dynamic library contributes no atoms to +the initial graph of atoms. Instead, (like static libraries) if there are +"undefined" atoms in the master graph of all atoms, then each dynamic library is +checked to see if exports the required symbol. If so, a "shared library" atom is +instantiated by the by the reader which the linker uses to replace the +"undefined" atom. + +Linking Steps +------------- + +Through the use of abstract Atoms, the core of linking is architecture +independent and file format independent. All command line parsing is factored +out into a separate "options" abstraction which enables the linker to be driven +with different command line sets. + +The overall steps in linking are: + + #. Command line processing + + #. Parsing input files + + #. Resolving + + #. Passes/Optimizations + + #. Generate output file + +The Resolving and Passes steps are done purely on the master graph of atoms, so +they have no notion of file formats such as mach-o or ELF. + + +Input Files +~~~~~~~~~~~ + +Existing developer tools using different file formats for object files. +A goal of lld is to be file format independent. This is done +through a plug-in model for reading object files. The lld::Reader is the base +class for all object file readers. A Reader follows the factory method pattern. +A Reader instantiates an lld::File object (which is a graph of Atoms) from a +given object file (on disk or in-memory). + +Every Reader subclass defines its own "options" class (for instance the mach-o +Reader defines the class ReaderOptionsMachO). This options class is the +one-and-only way to control how the Reader operates when parsing an input file +into an Atom graph. For instance, you may want the Reader to only accept +certain architectures. The options class can be instantiated from command +line options, or it can be subclassed and the ivars programmatically set. + + +Resolving +~~~~~~~~~ + +The resolving step takes all the atoms' graphs from each object file and +combines them into one master object graph. Unfortunately, it is not as simple +as appending the atom list from each file into one big list. There are many +cases where atoms need to be coalesced. That is, two or more atoms need to be +coalesced into one atom. This is necessary to support: C language "tentative +definitions", C++ weak symbols for templates and inlines defined in headers, +replacing undefined atoms with actual definition atoms, and for merging copies +of constants like c-strings and floating point constants. + +The linker support coalescing by-name and by-content. By-name is used for +tentative definitions and weak symbols. By-content is used for constant data +that can be merged. + +The resolving process maintains some global linking "state", including a "symbol +table" which is a map from llvm::StringRef to lld::Atom*. With these data +structures, the linker iterates all atoms in all input files. For each atom, it +checks if the atom is named and has a global or hidden scope. If so, the atom +is added to the symbol table map. If there already is a matching atom in that +table, that means the current atom needs to be coalesced with the found atom, or +it is a multiple definition error. + +When all initial input file atoms have been processed by the resolver, a scan is +made to see if there are any undefined atoms in the graph. If there are, the +linker scans all libraries (both static and dynamic) looking for definitions to +replace the undefined atoms. It is an error if any undefined atoms are left +remaining. + +Dead code stripping (if requested) is done at the end of resolving. The linker +does a simple mark-and-sweep. It starts with "root" atoms (like "main" in a main +executable) and follows each references and marks each Atom that it visits as +"live". When done, all atoms not marked "live" are removed. + +The result of the Resolving phase is the creation of an lld::File object. The +goal is that the lld::File model is **the** internal representation +throughout the linker. The file readers parse (mach-o, ELF, COFF) into an +lld::File. The file writers (mach-o, ELF, COFF) taken an lld::File and produce +their file kind, and every Pass only operates on an lld::File. This is not only +a simpler, consistent model, but it enables the state of the linker to be dumped +at any point in the link for testing purposes. + + +Passes +~~~~~~ + +The Passes step is an open ended set of routines that each get a change to +modify or enhance the current lld::File object. Some example Passes are: + + * stub (PLT) generation + + * GOT instantiation + + * order_file optimization + + * branch island generation + + * branch shim generation + + * Objective-C optimizations (Darwin specific) + + * TLV instantiation (Darwin specific) + + * DTrace probe processing (Darwin specific) + + * compact unwind encoding (Darwin specific) + + +Some of these passes are specific to Darwin's runtime environments. But many of +the passes are applicable to any OS (such as generating branch island for out of +range branch instructions). + +The general structure of a pass is to iterate through the atoms in the current +lld::File object, inspecting each atom and doing something. For instance, the +stub pass, looks for call sites to shared library atoms (e.g. call to printf). +It then instantiates a "stub" atom (PLT entry) and a "lazy pointer" atom for +each proxy atom needed, and these new atoms are added to the current lld::File +object. Next, all the noted call sites to shared library atoms have their +References altered to point to the stub atom instead of the shared library atom. + + +Generate Output File +~~~~~~~~~~~~~~~~~~~~ + +Once the passes are done, the output file writer is given current lld::File +object. The writer's job is to create the executable content file wrapper and +place the content of the atoms into it. + +lld uses a plug-in model for writing output files. All concrete writers (e.g. +ELF, mach-o, etc) are subclasses of the lld::Writer class. + +Unlike the Reader class which has just one method to instantiate an lld::File, +the Writer class has multiple methods. The crucial method is to generate the +output file, but there are also methods which allow the Writer to contribute +Atoms to the resolver and specify passes to run. + +An example of contributing +atoms is that if the Writer knows a main executable is being linked and such +an executable requires a specially named entry point (e.g. "_main"), the Writer +can add an UndefinedAtom with that special name to the resolver. This will +cause the resolver to issue an error if that symbol is not defined. + +Sometimes a Writer supports lazily created symbols, such as names for the start +of sections. To support this, the Writer can create a File object which vends +no initial atoms, but does lazily supply atoms by name as needed. + +Every Writer subclass defines its own "options" class (for instance the mach-o +Writer defines the class WriterOptionsMachO). This options class is the +one-and-only way to control how the Writer operates when producing an output +file from an Atom graph. For instance, you may want the Writer to optimize +the output for certain OS versions, or strip local symbols, etc. The options +class can be instantiated from command line options, or it can be subclassed +and the ivars programmatically set. + + +lld::File representations +------------------------- + +Just as LLVM has three representations of its IR model, lld has three +representations of its File/Atom/Reference model: + + * In memory, abstract C++ classes (lld::Atom, lld::Reference, and lld::File). + + * textual (in YAML) + + * binary format ("native") + +Binary File Format +~~~~~~~~~~~~~~~~~~ + +In theory, lld::File objects could be written to disk in an existing Object File +format standard (e.g. ELF). Instead we choose to define a new binary file +format. There are two main reasons for this: fidelity and performance. In order +for lld to work as a linker on all platforms, its internal model must be rich +enough to model all CPU and OS linking features. But if we choose an existing +Object File format as the lld binary format, that means an on going need to +retrofit each platform specific feature needed from alternate platforms into the +existing Object File format. Having our own "native" binary format side steps +that issue. We still need to be able to binary encode all the features, but +once the in-memory model can represent the feature, it is straight forward to +binary encode it. + +The reason to use a binary file format at all, instead of a textual file format, +is speed. You want the binary format to be as fast as possible to read into the +in-memory model. Given that we control the in-memory model and the binary +format, the obvious way to make reading super fast it to make the file format be +basically just an array of atoms. The reader just mmaps in the file and looks +at the header to see how many atoms there are and instantiate that many atom +objects with the atom attribute information coming from that array. The trick +is designing this in a way that can be extended as the Atom mode evolves and new +attributes are added. + +The native object file format starts with a header that lists how many "chunks" +are in the file. A chunk is an array of "ivar data". The native file reader +instantiates an array of Atom objects (with one large malloc call). Each atom +contains just a pointer to its vtable and a pointer to its ivar data. All +methods on lld::Atom are virtual, so all the method implementations return +values based on the ivar data to which it has a pointer. If a new linking +features is added which requires a change to the lld::Atom model, a new native +reader class (e.g. version 2) is defined which knows how to read the new feature +information from the new ivar data. The old reader class (e.g. version 1) is +updated to do its best to model (the lack of the new feature) given the old ivar +data in existing native object files. + +With this model for the native file format, files can be read and turned +into the in-memory graph of lld::Atoms with just a few memory allocations. +And the format can easily adapt over time to new features. + +The binary file format follows the ReaderWriter patterns used in lld. The lld +library comes with the classes: ReaderNative and WriterNative. So, switching +between file formats is as easy as switching which Reader subclass is used. + + +Textual representations in YAML +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In designing a textual format we want something easy for humans to read and easy +for the linker to parse. Since an atom has lots of attributes most of which are +usually just the default, we should define default values for every attribute so +that those can be omitted from the text representation. Here is the atoms for a +simple hello world program expressed in YAML:: + + target-triple: x86_64-apple-darwin11 + + atoms: + - name: _main + scope: global + type: code + content: [ 55, 48, 89, e5, 48, 8d, 3d, 00, 00, 00, 00, 30, c0, e8, 00, 00, + 00, 00, 31, c0, 5d, c3 ] + fixups: + - offset: 07 + kind: pcrel32 + target: 2 + - offset: 0E + kind: call32 + target: _fprintf + + - type: c-string + content: [ 73, 5A, 00 ] + + ... + +The biggest use for the textual format will be writing test cases. Writing test +cases in C is problematic because the compiler may vary its output over time for +its own optimization reasons which my inadvertently disable or break the linker +feature trying to be tested. By writing test cases in the linkers own textual +format, we can exactly specify every attribute of every atom and thus target +specific linker logic. + +The textual/YAML format follows the ReaderWriter patterns used in lld. The lld +library comes with the classes: ReaderYAML and WriterYAML. + + +Testing +------- + +The lld project contains a test suite which is being built up as new code is +added to lld. All new lld functionality should have a tests added to the test +suite. The test suite is `lit `_ driven. Each +test is a text file with comments telling lit how to run the test and check the +result To facilitate testing, the lld project builds a tool called lld-core. +This tool reads a YAML file (default from stdin), parses it into one or more +lld::File objects in memory and then feeds those lld::File objects to the +resolver phase. The output of the resolver is written as a native object file. +It is then read back in using the native object file reader and then pass to the +YAML writer. This round-about path means that all three representations +(in-memory, binary, and text) are exercised, and any new feature has to work in +all the representations to pass the test. + + +Resolver testing +~~~~~~~~~~~~~~~~ + +Basic testing is the "core linking" or resolving phase. That is where the +linker merges object files. All test cases are written in YAML. One feature of +YAML is that it allows multiple "documents" to be encoding in one YAML stream. +That means one text file can appear to the linker as multiple .o files - the +normal case for the linker. + +Here is a simple example of a core linking test case. It checks that an +undefined atom from one file will be replaced by a definition from another +file:: + + # RUN: lld-core %s | FileCheck %s + + # + # Test that undefined atoms are replaced with defined atoms. + # + + --- + atoms: + - name: foo + definition: undefined + --- + atoms: + - name: foo + scope: global + type: code + ... + + # CHECK: name: foo + # CHECK: scope: global + # CHECK: type: code + # CHECK-NOT: name: foo + # CHECK: ... + + +Passes testing +~~~~~~~~~~~~~~ + +Since Passes just operate on an lld::File object, the lld-core tool has the +option to run a particular pass (after resolving). Thus, you can write a YAML +test case with carefully crafted input to exercise areas of a Pass and the check +the resulting lld::File object as represented in YAML. + + +Design Issues +------------- + +There are a number of open issues in the design of lld. The plan is to wait and +make these design decisions when we need to. + + +Debug Info +~~~~~~~~~~ + +Currently, the lld model says nothing about debug info. But the most popular +debug format is DWARF and there is some impedance mismatch with the lld model +and DWARF. In lld there are just Atoms and only Atoms that need to be in a +special section at runtime have an associated section. Also, Atoms do not have +addresses. The way DWARF is spec'ed different parts of DWARF are supposed to go +into specially named sections and the DWARF references function code by address. + +CPU and OS specific functionality +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently, lld has an abstract "Platform" that deals with any CPU or OS specific +differences in linking. We just keep adding virtual methods to the base +Platform class as we find linking areas that might need customization. At some +point we'll need to structure this better. + + +File Attributes +~~~~~~~~~~~~~~~ + +Currently, lld::File just has a path and a way to iterate its atoms. We will +need to add more attributes on a File. For example, some equivalent to the +target triple. There is also a number of cached or computed attributes that +could make various Passes more efficient. For instance, on Darwin there are a +number of Objective-C optimizations that can be done by a Pass. But it would +improve the plain C case if the Objective-C optimization Pass did not have to +scan all atoms looking for any Objective-C data structures. This could be done +if the lld::File object had an attribute that said if the file had any +Objective-C data in it. The Resolving phase would then be required to "merge" +that attribute as object files are added. diff --git a/external/bsd/llvm/dist/lld/docs/development.rst b/external/bsd/llvm/dist/lld/docs/development.rst new file mode 100644 index 000000000..918e1778b --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/development.rst @@ -0,0 +1,48 @@ +.. _development: + +Development +=========== + +lld is developed as part of the `LLVM `_ project. + +Using C++11 in lld +------------------ + +:doc:`C++11`. + +Creating a Reader +----------------- + +See the :ref:`Creating a Reader ` guide. + + +Modifying the Driver +-------------------- + +See :doc:`Driver`. + + +Debugging +--------- + +You can run lld with ``-mllvm -debug`` command line options to enable debugging +printouts. If you want to enable debug information for some specific pass, you +can run it with ``-mllvm '-debug-only='``, where pass is a name used in +the ``DEBUG_WITH_TYPE()`` macro. + + + +Documentation +------------- + +The project documentation is written in reStructuredText and generated using the +`Sphinx `_ documentation generator. For more +information on writing documentation for the project, see the +:ref:`sphinx_intro`. + +.. toctree:: + :hidden: + + C++11 + Readers + Driver diff --git a/external/bsd/llvm/dist/lld/docs/getting_started.rst b/external/bsd/llvm/dist/lld/docs/getting_started.rst new file mode 100644 index 000000000..d1efcc04d --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/getting_started.rst @@ -0,0 +1,106 @@ +.. _getting_started: + +Getting Started: Building and Running lld +========================================= + +This page gives you the shortest path to checking out and building lld. If you +run into problems, please file bugs in the `LLVM Bugzilla`__ + +__ http://llvm.org/bugs/ + +Building lld +------------ + +On Unix-like Systems +~~~~~~~~~~~~~~~~~~~~ + +1. Get the required tools. + + * `CMake 2.8`_\+. + * make (or any build system CMake supports). + * `Clang 3.1`_\+ or GCC 4.7+ (C++11 support is required). + + * If using Clang, you will also need `libc++`_. + * `Python 2.4`_\+ (not 3.x) for running tests. + +.. _CMake 2.8: http://www.cmake.org/cmake/resources/software.html +.. _Clang 3.1: http://clang.llvm.org/ +.. _libc++: http://libcxx.llvm.org/ +.. _Python 2.4: http://python.org/download/ + +2. Check out LLVM:: + + $ cd path/to/llvm-project + $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm + +3. Check out lld:: + + $ cd llvm/tools + $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld + + * lld can also be checked out to ``path/to/llvm-project`` and built as an external + project. + +4. Build LLVM and lld:: + + $ cd path/to/llvm-build/llvm (out of source build required) + $ cmake -G "Unix Makefiles" path/to/llvm-project/llvm + $ make + + * If you want to build with clang and it is not the default compiler or + it is installed in an alternate location, you'll need to tell the cmake tool + the location of the C and C++ compiler via CMAKE_C_COMPILER and + CMAKE_CXX_COMPILER. For example:: + + $ cmake -DCMAKE_CXX_COMPILER=/path/to/clang++ -DCMAKE_C_COMPILER=/path/to/clang ... + +5. Test:: + + $ make lld-test + +Using Visual Studio +~~~~~~~~~~~~~~~~~~~ + +#. Get the required tools. + + * `CMake 2.8`_\+. + * `Visual Studio 11`_ (required for C++11 support) + * `Python 2.4`_\+ (not 3.x) for running tests. + +.. _CMake 2.8: http://www.cmake.org/cmake/resources/software.html +.. _Visual Studio 11: http://www.microsoft.com/visualstudio/11/en-us +.. _Python 2.4: http://python.org/download/ + +#. Check out LLVM:: + + $ cd path/to/llvm-project + $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm + +#. Check out lld:: + + $ cd llvm/tools + $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld + + * lld can also be checked out to ``path/to/llvm-project`` and built as an external + project. + +#. Generate Visual Studio project files:: + + $ cd path/to/llvm-build/llvm (out of source build required) + $ cmake -G "Visual Studio 11" path/to/llvm-project/llvm + +#. Build + + * Open LLVM.sln in Visual Studio. + * Build the ``ALL_BUILD`` target. + +#. Test + + * Build the ``lld-test`` target. + +More Information +~~~~~~~~~~~~~~~~ + +For more information on using CMake see the `LLVM CMake guide`_. + +.. _LLVM CMake guide: http://llvm.org/docs/CMake.html diff --git a/external/bsd/llvm/dist/lld/docs/hello.png b/external/bsd/llvm/dist/lld/docs/hello.png new file mode 100644 index 0000000000000000000000000000000000000000..70df111f1abd151f2a0ffe133bb6d00b4467d73e GIT binary patch literal 27616 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 WeM-GeSUR|TI9W+0iBd76p#K7$0(0X4 literal 0 HcmV?d00001 diff --git a/external/bsd/llvm/dist/lld/docs/index.rst b/external/bsd/llvm/dist/lld/docs/index.rst new file mode 100644 index 000000000..8fa3d8729 --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/index.rst @@ -0,0 +1,82 @@ +.. _index: + +lld - The LLVM Linker +===================== + +lld is a new set of modular code for creating linker tools. + +* End-User Features: + + * Compatible with existing linker options + * Reads standard Object Files (e.g. ELF, Mach-O, PE/COFF) + * Writes standard Executable Files (e.g. ELF, Mach-O, PE) + * Fast link times + * Minimal memory use + * Remove clang's reliance on "the system linker" + * Uses the LLVM `"UIUC" BSD-Style license`__. + +* Applications: + + * Modular design + * Support cross linking + * Easy to add new CPU support + * Can be built as static tool or library + +* Design and Implementation: + + * Extensive unit tests + * Internal linker model can be dumped/read to textual format + * Internal linker model can be dumped/read to a new native format + * Native format designed to be fast to read and write + * Additional linking features can be plugged in as "passes" + * OS specific and CPU specific code factored out + +Why a new linker? +----------------- + +The fact that clang relies on whatever linker tool you happen to have installed +means that clang has been very conservative adopting features which require a +recent linker. + +In the same way that the MC layer of LLVM has removed clang's reliance on the +system assembler tool, the lld project will remove clang's reliance on the +system linker tool. + + +Current Status +-------------- + +lld is in its early stages of development. + +It can currently self host on Linux x86-64 with -static. + +Source +------ + +lld is available in the LLVM SVN repository:: + + svn co http://llvm.org/svn/llvm-project/lld/trunk + +lld is also available via the read-only git mirror:: + + git clone http://llvm.org/git/lld.git + +Contents +-------- + +.. toctree:: + :maxdepth: 2 + + design + getting_started + development + open_projects + sphinx_intro + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`search` + +__ http://llvm.org/docs/DeveloperPolicy.html#license diff --git a/external/bsd/llvm/dist/lld/docs/llvm-theme/layout.html b/external/bsd/llvm/dist/lld/docs/llvm-theme/layout.html new file mode 100644 index 000000000..0cd0918ea --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/llvm-theme/layout.html @@ -0,0 +1,22 @@ +{# + sphinxdoc/layout.html + ~~~~~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the sphinxdoc theme. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{% extends "basic/layout.html" %} + +{% block relbar1 %} + +{{ super() }} +{% endblock %} + +{# put the sidebar before the body #} +{% block sidebar1 %}{{ sidebar() }}{% endblock %} +{% block sidebar2 %}{% endblock %} diff --git a/external/bsd/llvm/dist/lld/docs/llvm-theme/static/contents.png b/external/bsd/llvm/dist/lld/docs/llvm-theme/static/contents.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb82154a1748d507925865d3fbf7508d62483e5 GIT binary patch literal 202 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 Z?KG8a2Cm$O;IlqJQdCZ)TF4;q{{RiG|G@wN literal 0 HcmV?d00001 diff --git a/external/bsd/llvm/dist/lld/docs/llvm-theme/static/navigation.png b/external/bsd/llvm/dist/lld/docs/llvm-theme/static/navigation.png new file mode 100644 index 0000000000000000000000000000000000000000..1081dc1439fb984dfa7ef627afe3c7dc476fdbce GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI|!3HFkf4uMuBv2gW?!>U}oXkrghqJ&VvY3H^ zTNs2H8D`Cq01C2~c>21s-(chw7$R|bZ|_0D0|q>YSbqDzW^|HYIk%*-&O)*` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\lld.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\lld.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/external/bsd/llvm/dist/lld/docs/open_projects.rst b/external/bsd/llvm/dist/lld/docs/open_projects.rst new file mode 100644 index 000000000..e7b631bea --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/open_projects.rst @@ -0,0 +1,13 @@ +.. _open_projects: + +Open Projects +============= + +.. include:: ../include/lld/Core/TODO.txt +.. include:: ../lib/Core/TODO.txt +.. include:: ../tools/lld/TODO.txt + +Documentation TODOs +~~~~~~~~~~~~~~~~~~~ + +.. todolist:: diff --git a/external/bsd/llvm/dist/lld/docs/sphinx_intro.rst b/external/bsd/llvm/dist/lld/docs/sphinx_intro.rst new file mode 100644 index 000000000..6845bc812 --- /dev/null +++ b/external/bsd/llvm/dist/lld/docs/sphinx_intro.rst @@ -0,0 +1,147 @@ +.. _sphinx_intro: + +Sphinx Introduction for LLVM Developers +======================================= + +This document is intended as a short and simple introduction to the Sphinx +documentation generation system for LLVM developers. + +Quickstart +---------- + +To get started writing documentation, you will need to: + + 1. Have the Sphinx tools :ref:`installed `. + + 2. Understand how to :ref:`build the documentation + `. + + 3. Start :ref:`writing documentation `! + +.. _installing_sphinx: + +Installing Sphinx +~~~~~~~~~~~~~~~~~ + +You should be able to install Sphinx using the standard Python package +installation tool ``easy_install``, as follows:: + + $ sudo easy_install sphinx + Searching for sphinx + Reading http://pypi.python.org/simple/sphinx/ + Reading http://sphinx.pocoo.org/ + Best match: Sphinx 1.1.3 + ... more lines here .. + +If you do not have root access (or otherwise want to avoid installing Sphinx in +system directories) see the section on :ref:`installing_sphinx_in_a_venv` . + +If you do not have the ``easy_install`` tool on your system, you should be able +to install it using: + + Linux + Use your distribution's standard package management tool to install it, + i.e., ``apt-get install easy_install`` or ``yum install easy_install``. + + Mac OS X + All modern Mac OS X systems come with ``easy_install`` as part of the base + system. + + Windows + See the `setuptools `_ package web + page for instructions. + + +.. _building_the_documentation: + +Building the documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to build the documentation, all you should need to do is change to the +``docs`` directory and invoke make as follows:: + + $ cd path/to/project/docs + $ make html + +Note that on Windows there is a ``make.bat`` command in the docs directory which +supplies the same interface as the ``Makefile``. + +That command will invoke ``sphinx-build`` with the appropriate options for the +project, and generate the HTML documentation in a ``_build`` subdirectory. You +can browse it starting from the index page by visiting +``_build/html/index.html``. + +Sphinx supports a wide variety of generation formats (including LaTeX, man +pages, and plain text). The ``Makefile`` includes a number of convenience +targets for invoking ``sphinx-build`` appropriately, the common ones are: + + make html + Generate the HTML output. + + make latexpdf + Generate LaTeX documentation and convert to a PDF. + + make man + Generate man pages. + + +.. _writing_documentation: + +Writing documentation +~~~~~~~~~~~~~~~~~~~~~ + +The documentation itself is written in the reStructuredText (ReST) format, and Sphinx +defines additional tags to support features like cross-referencing. + +The ReST format itself is organized around documents mostly being readable +plaintext documents. You should generally be able to write new documentation +easily just by following the style of the existing documentation. + +If you want to understand the formatting of the documents more, the best place +to start is Sphinx's own `ReST Primer `_. + + +Learning More +------------- + +If you want to learn more about the Sphinx system, the best place to start is +the Sphinx documentation itself, available `here +`_. + + +.. _installing_sphinx_in_a_venv: + +Installing Sphinx in a Virtual Environment +------------------------------------------ + +Most Python developers prefer to work with tools inside a *virtualenv* (virtual +environment) instance, which functions as an application sandbox. This avoids +polluting your system installation with different packages used by various +projects (and ensures that dependencies for different packages don't conflict +with one another). Of course, you need to first have the virtualenv software +itself which generally would be installed at the system level:: + + $ sudo easy_install virtualenv + +but after that you no longer need to install additional packages in the system +directories. + +Once you have the *virtualenv* tool itself installed, you can create a +virtualenv for Sphinx using:: + + $ virtualenv ~/my-sphinx-install + New python executable in /Users/dummy/my-sphinx-install/bin/python + Installing setuptools............done. + Installing pip...............done. + + $ ~/my-sphinx-install/bin/easy_install sphinx + ... install messages here ... + +and from now on you can "activate" the *virtualenv* using:: + + $ source ~/my-sphinx-install/bin/activate + +which will change your PATH to ensure the sphinx-build tool from inside the +virtual environment will be used. See the `virtualenv website +`_ for more information on using +virtual environments. diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/AbsoluteAtom.h b/external/bsd/llvm/dist/lld/include/lld/Core/AbsoluteAtom.h new file mode 100644 index 000000000..f400061a8 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/AbsoluteAtom.h @@ -0,0 +1,43 @@ +//===- Core/AbsoluteAtom.h - An absolute Atom -----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_ABSOLUTE_ATOM_H +#define LLD_CORE_ABSOLUTE_ATOM_H + +#include "lld/Core/Atom.h" + +namespace lld { + +/// An AbsoluteAtom has no content. +/// It exists to represent content at fixed addresses in memory. +class AbsoluteAtom : public Atom { +public: + + virtual uint64_t value() const = 0; + + /// scope - The visibility of this atom to other atoms. C static functions + /// have scope scopeTranslationUnit. Regular C functions have scope + /// scopeGlobal. Functions compiled with visibility=hidden have scope + /// scopeLinkageUnit so they can be see by other atoms being linked but not + /// by the OS loader. + virtual Scope scope() const = 0; + + static inline bool classof(const Atom *a) { + return a->definition() == definitionAbsolute; + } + static inline bool classof(const AbsoluteAtom *) { return true; } + +protected: + AbsoluteAtom() : Atom(definitionAbsolute) {} + virtual ~AbsoluteAtom() {} +}; + +} // namespace lld + +#endif // LLD_CORE_ABSOLUTE_ATOM_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/ArchiveLibraryFile.h b/external/bsd/llvm/dist/lld/include/lld/Core/ArchiveLibraryFile.h new file mode 100644 index 000000000..251363d1d --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/ArchiveLibraryFile.h @@ -0,0 +1,48 @@ +//===- Core/ArchiveLibraryFile.h - Models static library ------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_ARCHIVE_LIBRARY_FILE_H +#define LLD_CORE_ARCHIVE_LIBRARY_FILE_H + +#include "lld/Core/File.h" + +namespace lld { + +/// +/// The ArchiveLibraryFile subclass of File is used to represent unix +/// static library archives. These libraries provide no atoms to the +/// initial set of atoms linked. Instead, when the Resolver will query +/// ArchiveLibraryFile instances for specific symbols names using the +/// find() method. If the archive contains an object file which has a +/// DefinedAtom whose scope is not translationUnit, then that entire +/// object file File is returned. +/// +class ArchiveLibraryFile : public File { +public: + static inline bool classof(const File *f) { + return f->kind() == kindArchiveLibrary; + } + + /// Check if any member of the archive contains an Atom with the + /// specified name and return the File object for that member, or nullptr. + virtual const File *find(StringRef name, bool dataSymbolOnly) const = 0; + + virtual const LinkingContext &getLinkingContext() const { return _context; } + +protected: + /// only subclasses of ArchiveLibraryFile can be instantiated + ArchiveLibraryFile(const LinkingContext &context, StringRef path) + : File(path, kindArchiveLibrary), _context(context) {} + + const LinkingContext &_context; +}; + +} // namespace lld + +#endif // LLD_CORE_ARCHIVE_LIBRARY_FILE_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Atom.h b/external/bsd/llvm/dist/lld/include/lld/Core/Atom.h new file mode 100644 index 000000000..dd23d7ca4 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Atom.h @@ -0,0 +1,84 @@ +//===- Core/Atom.h - A node in linking graph ------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_ATOM_H +#define LLD_CORE_ATOM_H + +#include "lld/Core/LLVM.h" + +#include "llvm/Support/DataTypes.h" + +#include + +namespace llvm { + class StringRef; +} + +namespace lld { + +class File; + +/// +/// The linker has a Graph Theory model of linking. An object file is seen +/// as a set of Atoms with References to other Atoms. Each Atom is a node +/// and each Reference is an edge. An Atom can be a DefinedAtom which has +/// content or a UndefinedAtom which is a placeholder and represents an +/// undefined symbol (extern declaration). +/// +class Atom { +public: + /// Whether this atom is defined or a proxy for an undefined symbol + enum Definition { + definitionRegular, ///< Normal C/C++ function or global variable. + definitionAbsolute, ///< Asm-only (foo = 10). Not tied to any content. + definitionUndefined, ///< Only in .o files to model reference to undef. + definitionSharedLibrary ///< Only in shared libraries to model export. + }; + + /// The scope in which this atom is acessible to other atoms. + enum Scope { + scopeTranslationUnit, ///< Accessible only to atoms in the same translation + /// unit (e.g. a C static). + scopeLinkageUnit, ///< Accessible to atoms being linked but not visible + /// to runtime loader (e.g. visibility=hidden). + scopeGlobal ///< Accessible to all atoms and visible to runtime + /// loader (e.g. visibility=default). + }; + + + /// file - returns the File that produced/owns this Atom + virtual const File& file() const = 0; + + /// name - The name of the atom. For a function atom, it is the (mangled) + /// name of the function. + virtual StringRef name() const = 0; + + /// definition - Whether this atom is a definition or represents an undefined + /// symbol. + Definition definition() const { return _definition; } + + static inline bool classof(const Atom *a) { return true; } + +protected: + /// Atom is an abstract base class. Only subclasses can access constructor. + explicit Atom(Definition def) : _definition(def) {} + + /// The memory for Atom objects is always managed by the owning File + /// object. Therefore, no one but the owning File object should call + /// delete on an Atom. In fact, some File objects may bulk allocate + /// an array of Atoms, so they cannot be individually deleted by anyone. + virtual ~Atom() {} + +private: + Definition _definition; +}; + +} // namespace lld + +#endif // LLD_CORE_ATOM_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/DefinedAtom.h b/external/bsd/llvm/dist/lld/include/lld/Core/DefinedAtom.h new file mode 100644 index 000000000..4be7fac7b --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/DefinedAtom.h @@ -0,0 +1,357 @@ +//===- Core/DefinedAtom.h - An Atom with content --------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_DEFINED_ATOM_H +#define LLD_CORE_DEFINED_ATOM_H + +#include "lld/Core/Atom.h" +#include "lld/Core/Reference.h" + +namespace llvm { + template + class ArrayRef; + class StringRef; +} + +namespace lld { +class File; + +/// \brief The fundamental unit of linking. +/// +/// A C function or global variable is an atom. An atom has content and +/// attributes. The content of a function atom is the instructions that +/// implement the function. The content of a global variable atom is its +/// initial bytes. +/// +/// Here are some example attribute sets for common atoms. If a particular +/// attribute is not listed, the default values are: definition=regular, +/// sectionChoice=basedOnContent, scope=translationUnit, merge=no, +/// deadStrip=normal, interposable=no +/// +/// C function: void foo() {}
    +/// name=foo, type=code, perm=r_x, scope=global +/// +/// C static function: staic void func() {}
    +/// name=func, type=code, perm=r_x +/// +/// C global variable: int count = 1;
    +/// name=count, type=data, perm=rw_, scope=global +/// +/// C tentative definition: int bar;
    +/// name=bar, type=zerofill, perm=rw_, scope=global, +/// merge=asTentative, interposable=yesAndRuntimeWeak +/// +/// Uninitialized C static variable: static int stuff;
    +/// name=stuff, type=zerofill, perm=rw_ +/// +/// Weak C function: __attribute__((weak)) void foo() {}
    +/// name=foo, type=code, perm=r_x, scope=global, merge=asWeak +/// +/// Hidden C function: __attribute__((visibility("hidden"))) void foo() {}
    +/// name=foo, type=code, perm=r_x, scope=linkageUnit +/// +/// No-dead-strip function: __attribute__((used)) void foo() {}
    +/// name=foo, type=code, perm=r_x, scope=global, deadStrip=never +/// +/// Non-inlined C++ inline method: inline void Foo::doit() {}
    +/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global, +/// mergeDupes=asWeak +/// +/// Non-inlined C++ inline method whose address is taken: +/// inline void Foo::doit() {}
    +/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global, +/// mergeDupes=asAddressedWeak +/// +/// literal c-string: "hello"
    +/// name="" type=cstring, perm=r__, scope=linkageUnit +/// +/// literal double: 1.234
    +/// name="" type=literal8, perm=r__, scope=linkageUnit +/// +/// constant: { 1,2,3 }
    +/// name="" type=constant, perm=r__, scope=linkageUnit +/// +/// Pointer to initializer function:
    +/// name="" type=initializer, perm=rw_l, +/// sectionChoice=customRequired +/// +/// C function place in custom section: __attribute__((section("__foo"))) +/// void foo() {}
    +/// name=foo, type=code, perm=r_x, scope=global, +/// sectionChoice=customRequired, customSectionName=__foo +/// +class DefinedAtom : public Atom { +public: + enum Interposable { + interposeNo, // linker can directly bind uses of this atom + interposeYes, // linker must indirect (through GOT) uses + interposeYesAndRuntimeWeak // must indirect and mark symbol weak in final + // linked image + }; + + enum Merge { + mergeNo, // Another atom with same name is error + mergeAsTentative, // Is ANSI C tentative defintion, can be coalesced + mergeAsWeak, // is C++ inline definition that was not inlined, + // but address was not taken, so atom can be hidden + // by linker + mergeAsWeakAndAddressUsed,// is C++ definition inline definition whose + // address was taken. + mergeByContent // merge with other constants with same content + }; + + enum ContentType { + typeUnknown, // for use with definitionUndefined + typeCode, // executable code + typeResolver, // function which returns address of target + typeBranchIsland, // linker created for large binaries + typeBranchShim, // linker created to switch thumb mode + typeStub, // linker created for calling external function + typeStubHelper, // linker created for initial stub binding + typeConstant, // a read-only constant + typeCString, // a zero terminated UTF8 C string + typeUTF16String, // a zero terminated UTF16 string + typeCFI, // a FDE or CIE from dwarf unwind info + typeLSDA, // extra unwinding info + typeLiteral4, // a four-btye read-only constant + typeLiteral8, // an eight-btye read-only constant + typeLiteral16, // a sixteen-btye read-only constant + typeData, // read-write data + typeDataFast, // allow data to be quickly accessed + typeZeroFill, // zero-fill data + typeZeroFillFast, // allow zero-fill data to be quicky accessed + typeConstData, // read-only data after dynamic linker is done + typeObjC1Class, // ObjC1 class [Darwin] + typeLazyPointer, // pointer through which a stub jumps + typeLazyDylibPointer, // pointer through which a stub jumps [Darwin] + typeCFString, // NS/CFString object [Darwin] + typeGOT, // pointer to external symbol + typeInitializerPtr, // pointer to initializer function + typeTerminatorPtr, // pointer to terminator function + typeCStringPtr, // pointer to UTF8 C string [Darwin] + typeObjCClassPtr, // pointer to ObjC class [Darwin] + typeObjC2CategoryList, // pointers to ObjC category [Darwin] + typeDTraceDOF, // runtime data for Dtrace [Darwin] + typeTempLTO, // temporary atom for bitcode reader + typeCompactUnwindInfo, // runtime data for unwinder [Darwin] + typeThunkTLV, // thunk used to access a TLV [Darwin] + typeTLVInitialData, // initial data for a TLV [Darwin] + typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin] + typeTLVInitializerPtr, // pointer to thread local initializer [Darwin] + typeDataDirectoryEntry, // linker created for data directory header [PECOFF] + typeThreadZeroFill, // Uninitialized thread local data(TBSS) [ELF] + typeThreadData, // Initialized thread local data(TDATA) [ELF] + typeRONote, // Identifies readonly note sections [ELF] + typeRWNote, // Identifies readwrite note sections [ELF] + typeNoAlloc, // Identifies non allocatable sections [ELF] + }; + + // Permission bits for atoms and segments. The order of these values are + // important, because the layout pass may sort atoms by permission if other + // attributes are the same. + enum ContentPermissions { + perm___ = 0, // mapped as unaccessible + permR__ = 8, // mapped read-only + permRW_ = 8 + 2, // mapped readable and writable + permRW_L = 8 + 2 + 1, // initially mapped r/w, then made read-only + // loader writable + permR_X = 8 + 4, // mapped readable and executable + permRWX = 8 + 2 + 4, // mapped readable and writable and executable + permUnknown = 16 // unknown or invalid permissions + }; + + enum SectionChoice { + sectionBasedOnContent, // linker infers final section based on content + sectionCustomPreferred, // linker may place in specific section + sectionCustomRequired // linker must place in specific section + }; + + enum SectionPosition { + sectionPositionStart, // atom must be at start of section (and zero size) + sectionPositionEarly, // atom should be near start of section + sectionPositionAny, // atom can be anywhere in section + sectionPositionEnd // atom must be at end of section (and zero size) + }; + + enum DeadStripKind { + deadStripNormal, // linker may dead strip this atom + deadStripNever, // linker must never dead strip this atom + deadStripAlways // linker must remove this atom if unused + }; + + enum DynamicExport { + /// \brief The linker may or may not export this atom dynamically depending + /// on the output type and other context of the link. + dynamicExportNormal, + /// \brief The linker will always export this atom dynamically. + dynamicExportAlways, + }; + + struct Alignment { + Alignment(int p2, int m = 0) + : powerOf2(p2) + , modulus(m) {} + + uint16_t powerOf2; + uint16_t modulus; + + bool operator==(const Alignment &rhs) const { + return (powerOf2 == rhs.powerOf2) && (modulus == rhs.modulus); + } + }; + + /// \brief returns a value for the order of this Atom within its file. + /// + /// This is used by the linker to order the layout of Atoms so that the + /// resulting image is stable and reproducible. + /// + /// Note that this should not be confused with ordinals of exported symbols in + /// Windows DLLs. In Windows terminology, ordinals are symbols' export table + /// indices (small integers) which can be used instead of symbol names to + /// refer items in a DLL. + virtual uint64_t ordinal() const = 0; + + /// \brief the number of bytes of space this atom's content will occupy in the + /// final linked image. + /// + /// For a function atom, it is the number of bytes of code in the function. + virtual uint64_t size() const = 0; + + /// \brief The visibility of this atom to other atoms. + /// + /// C static functions have scope scopeTranslationUnit. Regular C functions + /// have scope scopeGlobal. Functions compiled with visibility=hidden have + /// scope scopeLinkageUnit so they can be see by other atoms being linked but + /// not by the OS loader. + virtual Scope scope() const = 0; + + /// \brief Whether the linker should use direct or indirect access to this + /// atom. + virtual Interposable interposable() const = 0; + + /// \brief how the linker should handle if multiple atoms have the same name. + virtual Merge merge() const = 0; + + /// \brief The type of this atom, such as code or data. + virtual ContentType contentType() const = 0; + + /// \brief The alignment constraints on how this atom must be laid out in the + /// final linked image (e.g. 16-byte aligned). + virtual Alignment alignment() const = 0; + + /// \brief Whether this atom must be in a specially named section in the final + /// linked image, or if the linker can infer the section based on the + /// contentType(). + virtual SectionChoice sectionChoice() const = 0; + + /// \brief If sectionChoice() != sectionBasedOnContent, then this return the + /// name of the section the atom should be placed into. + virtual StringRef customSectionName() const = 0; + + /// \brief constraints on whether the linker may dead strip away this atom. + virtual SectionPosition sectionPosition() const = 0; + + /// \brief constraints on whether the linker may dead strip away this atom. + virtual DeadStripKind deadStrip() const = 0; + + /// \brief Under which conditions should this atom be dynamically exported. + virtual DynamicExport dynamicExport() const { + return dynamicExportNormal; + } + + /// \brief Returns the OS memory protections required for this atom's content + /// at runtime. + /// + /// A function atom is R_X, a global variable is RW_, and a read-only constant + /// is R__. + virtual ContentPermissions permissions() const; + + /// \brief means this is a zero size atom that exists to provide an alternate + /// name for another atom. Alias atoms must have a special Reference to the + /// atom they alias which the layout engine recognizes and forces the alias + /// atom to layout right before the target atom. + virtual bool isAlias() const = 0; + + /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's + /// content. + virtual ArrayRef rawContent() const = 0; + + /// This class abstracts iterating over the sequence of References + /// in an Atom. Concrete instances of DefinedAtom must implement + /// the derefIterator() and incrementIterator() methods. + class reference_iterator { + public: + reference_iterator(const DefinedAtom &a, const void *it) + : _atom(a), _it(it) { } + + const Reference *operator*() const { + return _atom.derefIterator(_it); + } + + const Reference *operator->() const { + return _atom.derefIterator(_it); + } + + bool operator!=(const reference_iterator &other) const { + return _it != other._it; + } + + reference_iterator &operator++() { + _atom.incrementIterator(_it); + return *this; + } + private: + const DefinedAtom &_atom; + const void *_it; + }; + + /// \brief Returns an iterator to the beginning of this Atom's References. + virtual reference_iterator begin() const = 0; + + /// \brief Returns an iterator to the end of this Atom's References. + virtual reference_iterator end() const = 0; + + static inline bool classof(const Atom *a) { + return a->definition() == definitionRegular; + } + + /// Utility for deriving permissions from content type + static ContentPermissions permissions(ContentType type); + + /// Utility function to check if the atom occupies file space + virtual bool occupiesDiskSpace() const { + ContentType atomContentType = contentType(); + return !(atomContentType == DefinedAtom::typeZeroFill || + atomContentType == DefinedAtom::typeZeroFillFast || + atomContentType == DefinedAtom::typeTLVInitialZeroFill || + atomContentType == DefinedAtom::typeThreadZeroFill); + } + +protected: + // DefinedAtom is an abstract base class. Only subclasses can access + // constructor. + DefinedAtom() : Atom(definitionRegular) { } + + // The memory for DefinedAtom objects is always managed by the owning File + // object. Therefore, no one but the owning File object should call delete on + // an Atom. In fact, some File objects may bulk allocate an array of Atoms, + // so they cannot be individually deleted by anyone. + virtual ~DefinedAtom() {} + + /// \brief Returns a pointer to the Reference object that the abstract + /// iterator "points" to. + virtual const Reference *derefIterator(const void *iter) const = 0; + + /// \brief Adjusts the abstract iterator to "point" to the next Reference + /// object for this Atom. + virtual void incrementIterator(const void *&iter) const = 0; +}; +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Error.h b/external/bsd/llvm/dist/lld/include/lld/Core/Error.h new file mode 100644 index 000000000..bda6b27ac --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Error.h @@ -0,0 +1,84 @@ +//===- Error.h - system_error extensions for lld ----------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This declares a new error_category for the lld library. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_ERROR_H +#define LLD_CORE_ERROR_H + +#include "llvm/Support/system_error.h" + +namespace lld { + +const llvm::error_category &native_reader_category(); + +enum class NativeReaderError { + success = 0, + unknown_file_format, + file_too_short, + file_malformed, + unknown_chunk_type, + memory_error, +}; + +inline llvm::error_code make_error_code(NativeReaderError e) { + return llvm::error_code(static_cast(e), native_reader_category()); +} + +const llvm::error_category &YamlReaderCategory(); + +enum class YamlReaderError { + success = 0, + unknown_keyword, + illegal_value +}; + +inline llvm::error_code make_error_code(YamlReaderError e) { + return llvm::error_code(static_cast(e), YamlReaderCategory()); +} + +const llvm::error_category &LinkerScriptReaderCategory(); + +enum class LinkerScriptReaderError { + success = 0, + parse_error +}; + +inline llvm::error_code make_error_code(LinkerScriptReaderError e) { + return llvm::error_code(static_cast(e), LinkerScriptReaderCategory()); +} + +/// \brief Errors returned by InputGraph functionality +const llvm::error_category &InputGraphErrorCategory(); + +enum class InputGraphError { + success = 0, + failure = 1, + no_more_elements, + no_more_files +}; + +inline llvm::error_code make_error_code(InputGraphError e) { + return llvm::error_code(static_cast(e), InputGraphErrorCategory()); +} + +} // end namespace lld + +namespace llvm { + +template <> struct is_error_code_enum : true_type {}; +template <> struct is_error_code_enum : true_type {}; +template <> +struct is_error_code_enum : true_type {}; +template <> struct is_error_code_enum : true_type {}; +} // end namespace llvm + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/File.h b/external/bsd/llvm/dist/lld/include/lld/Core/File.h new file mode 100644 index 000000000..26345c76a --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/File.h @@ -0,0 +1,251 @@ +//===- Core/File.h - A Container of Atoms ---------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_FILE_H +#define LLD_CORE_FILE_H + +#include "lld/Core/AbsoluteAtom.h" +#include "lld/Core/DefinedAtom.h" +#include "lld/Core/range.h" +#include "lld/Core/SharedLibraryAtom.h" +#include "lld/Core/LinkingContext.h" +#include "lld/Core/UndefinedAtom.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" + +#include + +namespace lld { + +class LinkingContext; + +/// Every Atom is owned by some File. A common scenario is for a single +/// object file (.o) to be parsed by some reader and produce a single +/// File object that represents the content of that object file. +/// +/// To iterate through the Atoms in a File there are four methods that +/// return collections. For instance to iterate through all the DefinedAtoms +/// in a File object use: +/// for (const DefinedAtoms *atom : file->defined()) { +/// } +/// +/// The Atom objects in a File are owned by the File object. The Atom objects +/// are destroyed when the File object is destroyed. +class File { +public: + virtual ~File(); + + /// \brief Kinds of files that are supported. + enum Kind { + kindObject, ///< object file (.o) + kindSharedLibrary, ///< shared library (.so) + kindArchiveLibrary, ///< archive (.a) + kindLinkerScript, ///< linker script + }; + + /// \brief Returns file kind. Need for dyn_cast<> on File objects. + Kind kind() const { + return _kind; + } + + /// \brief For error messages and debugging, this returns the path to the file + /// which was used to create this object (e.g. "/tmp/foo.o"). + StringRef path() const { + return _path; + } + + /// \brief Returns the path of the source file used to create the object + /// file which this (File) object represents. This information is usually + /// parsed out of the DWARF debug information. If the source file cannot + /// be ascertained, this method returns the empty string. + virtual StringRef translationUnitSource() const; + + /// Returns the command line order of the file. + uint64_t ordinal() const { + assert(_ordinal != UINT64_MAX); + return _ordinal; + } + + /// Returns true/false depending on whether an ordinal has been set. + bool hasOrdinal() const { return (_ordinal != UINT64_MAX); } + + /// Sets the command line order of the file. + void setOrdinal(uint64_t ordinal) const { _ordinal = ordinal; } + +public: + template class atom_iterator; // forward reference + + /// \brief For use interating over DefinedAtoms in this File. + typedef atom_iterator defined_iterator; + + /// \brief For use interating over UndefinedAtoms in this File. + typedef atom_iterator undefined_iterator; + + /// \brief For use interating over SharedLibraryAtoms in this File. + typedef atom_iterator shared_library_iterator; + + /// \brief For use interating over AbsoluteAtoms in this File. + typedef atom_iterator absolute_iterator; + + /// \brief Different object file readers may instantiate and manage atoms with + /// different data structures. This class is a collection abstraction. + /// Each concrete File instance must implement these atom_collection + /// methods to enable clients to interate the File's atoms. + template + class atom_collection { + public: + virtual ~atom_collection() { } + virtual atom_iterator begin() const = 0; + virtual atom_iterator end() const = 0; + virtual const T *deref(const void *it) const = 0; + virtual void next(const void *&it) const = 0; + virtual uint64_t size() const = 0; + }; + + /// \brief The class is the iterator type used to iterate through a File's + /// Atoms. This iterator delegates the work to the associated atom_collection + /// object. There are four kinds of Atoms, so this iterator is templated on + /// the four base Atom kinds. + template + class atom_iterator { + public: + atom_iterator(const atom_collection &c, const void *it) + : _collection(c), _it(it) { } + + const T *operator*() const { + return _collection.deref(_it); + } + const T *operator->() const { + + return _collection.deref(_it); + } + + bool operator!=(const atom_iterator &other) const { + return (this->_it != other._it); + } + + atom_iterator &operator++() { + _collection.next(_it); + return *this; + } + private: + const atom_collection &_collection; + const void *_it; + }; + + + /// \brief Must be implemented to return the atom_collection object for + /// all DefinedAtoms in this File. + virtual const atom_collection &defined() const = 0; + + /// \brief Must be implemented to return the atom_collection object for + /// all UndefinedAtomw in this File. + virtual const atom_collection &undefined() const = 0; + + /// \brief Must be implemented to return the atom_collection object for + /// all SharedLibraryAtoms in this File. + virtual const atom_collection &sharedLibrary() const = 0; + + /// \brief Must be implemented to return the atom_collection object for + /// all AbsoluteAtoms in this File. + virtual const atom_collection &absolute() const = 0; + + virtual const LinkingContext &getLinkingContext() const = 0; + +protected: + /// \brief only subclasses of File can be instantiated + File(StringRef p, Kind kind) : _path(p), _kind(kind), _ordinal(UINT64_MAX) {} + + /// \brief This is a convenience class for File subclasses which manage their + /// atoms as a simple std::vector<>. + template + class atom_collection_vector : public atom_collection { + public: + virtual atom_iterator begin() const { + return atom_iterator(*this, + _atoms.empty() ? 0 : reinterpret_cast(_atoms.data())); + } + + virtual atom_iterator end() const{ + return atom_iterator(*this, _atoms.empty() ? 0 : + reinterpret_cast(_atoms.data() + _atoms.size())); + } + + virtual const T *deref(const void *it) const { + return *reinterpret_cast(it); + } + + virtual void next(const void *&it) const { + const T *const *p = reinterpret_cast(it); + ++p; + it = reinterpret_cast(p); + } + + virtual uint64_t size() const { return _atoms.size(); } + + std::vector _atoms; + }; + + /// \brief This is a convenience class for File subclasses which need to + /// return an empty collection. + template + class atom_collection_empty : public atom_collection { + public: + virtual atom_iterator begin() const { + return atom_iterator(*this, nullptr); + } + virtual atom_iterator end() const{ + return atom_iterator(*this, nullptr); + } + virtual const T *deref(const void *it) const { + llvm_unreachable("empty collection should never be accessed"); + } + virtual void next(const void *&it) const { + } + virtual void push_back(const T *element) { + llvm_unreachable("empty collection should never be grown"); + } + virtual uint64_t size() const { return 0; } + }; + + static atom_collection_empty _noDefinedAtoms; + static atom_collection_empty _noUndefinedAtoms; + static atom_collection_empty _noSharedLibraryAtoms; + static atom_collection_empty _noAbsoluteAtoms; + +private: + StringRef _path; + Kind _kind; + mutable uint64_t _ordinal; +}; + +/// \brief A mutable File. +class MutableFile : public File { +public: + /// \brief Add an atom to the file. Invalidates iterators for all returned + /// containters. + virtual void addAtom(const Atom&) = 0; + + typedef range::iterator> DefinedAtomRange; + virtual DefinedAtomRange definedAtoms() = 0; + + virtual const LinkingContext &getLinkingContext() const { return _context; } + +protected: + /// \brief only subclasses of MutableFile can be instantiated + MutableFile(const LinkingContext &ctx, StringRef p) + : File(p, kindObject), _context(ctx) {} + +private: + const LinkingContext &_context; +}; +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/InputGraph.h b/external/bsd/llvm/dist/lld/include/lld/Core/InputGraph.h new file mode 100644 index 000000000..ad934dc3d --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/InputGraph.h @@ -0,0 +1,411 @@ +//===- lld/Core/InputGraph.h - Input Graph --------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Inputs to the linker in the form of a Graph. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_INPUT_GRAPH_H +#define LLD_CORE_INPUT_GRAPH_H + +#include "lld/Core/File.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/ArgList.h" + +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include + +namespace lld { + +class InputElement; +class LinkingContext; + +/// \brief The inputs to the linker are represented by an InputGraph. The +/// nodes in the input graph contains Input elements. The InputElements are +/// either Input Files or Control Options. The Input Files represent each Input +/// File to the linker and the control option specify what the linker needs +/// to do when it processes the option. +/// Each InputElement that is part of the Graph has an Ordinal value +/// associated with it. The ordinal value is needed for the Writer to figure out +/// the relative position of the arguments that appeared in the Command Line. +/// InputElements have a weight function that can be used to determine the +/// weight of the file, for statistical purposes. +class InputGraph { +public: + typedef std::vector > InputElementVectorT; + typedef InputElementVectorT::iterator InputElementIterT; + typedef std::vector > FileVectorT; + typedef FileVectorT::iterator FileIterT; + + /// Where do we want to insert the input element when calling the + /// insertElementAt, insertOneElementAt API's. + enum Position : uint8_t { + ANY, + BEGIN, + END + }; + + /// \brief Initialize the inputgraph + InputGraph() : _ordinal(0), _nextElementIndex(0) {} + + /// \brief Adds a node into the InputGraph + virtual bool addInputElement(std::unique_ptr); + + /// \brief Set Ordinals for all the InputElements that form the InputGraph + virtual bool assignOrdinals(); + + /// Destructor + virtual ~InputGraph() {} + + /// \brief Do postprocessing of the InputGraph if there is a need for the + /// to provide additional information to the user, also rearranges + /// InputElements by their ordinals. If an user wants to place an input file + /// at the desired position, the user can do that + virtual void doPostProcess(); + + range inputElements() { + return make_range(_inputArgs.begin(), _inputArgs.end()); + } + + /// \brief Validate the input graph + virtual bool validate(); + + // \brief Does the inputGraph contain any elements + size_t size() const { return _inputArgs.size(); } + + /// \brief Dump the input Graph + virtual bool dump(raw_ostream &diagnostics = llvm::errs()); + + InputElement &operator[](size_t index) const { + return (*_inputArgs[index]); + } + + /// \brief Insert a vector of elements into the input graph at position. + virtual void insertElementsAt(std::vector >, + Position position, size_t pos = 0); + + /// \brief Insert an element into the input graph at position. + virtual void insertOneElementAt(std::unique_ptr, + Position position, size_t pos = 0); + + /// \brief Helper functions for the resolver + virtual ErrorOr getNextInputElement(); + + /// \brief Set the index on what inputElement has to be returned + virtual error_code setNextElementIndex(uint32_t index = 0); + + /// \brief Reset the inputGraph for the inputGraph to start processing + /// files from the beginning + virtual error_code reset() { return setNextElementIndex(0); } + +protected: + // Input arguments + InputElementVectorT _inputArgs; + // Ordinals + int64_t _ordinal; + // Index of the next element to be processed + uint32_t _nextElementIndex; +}; + +/// \brief This describes each element in the InputGraph. The Kind +/// determines what the current node contains. +class InputElement { +public: + /// Each input element in the graph can be a File or a control + enum class Kind : uint8_t { + Control, // Represents a type associated with ControlNodes + SimpleFile, // Represents a type reserved for internal files + File // Represents a type associated with File Nodes + }; + + /// \brief Initialize the Input Element, The ordinal value of an input Element + /// is initially set to -1, if the user wants to override its ordinal, + /// let the user do it + InputElement(Kind type, int64_t ordinal = -1); + + virtual ~InputElement() {} + + /// Return the Element Type for an Input Element + virtual Kind kind() const { return _kind; } + + virtual void setOrdinal(int64_t ordinal) { + if (_ordinal != -1) + _ordinal = ordinal; + } + + virtual int64_t getOrdinal() const { return _ordinal; } + + virtual int64_t weight() const { return _weight; } + + virtual void setWeight(int64_t weight) { _weight = weight; } + + /// \brief validates the Input Element + virtual bool validate() = 0; + + /// \brief Dump the Input Element + virtual bool dump(raw_ostream &diagnostics) = 0; + + /// \brief parse the input element + virtual error_code parse(const LinkingContext &, raw_ostream &) = 0; + + /// \brief functions for the resolver to use + + /// Get the next file to be processed by the resolver + virtual ErrorOr getNextFile() = 0; + + /// \brief Set the resolve state for the element + virtual void setResolveState(uint32_t state) = 0; + + /// \brief Get the resolve state for the element + virtual uint32_t getResolveState() const = 0; + + /// \brief Reset the next index + virtual void resetNextIndex() = 0; + +protected: + Kind _kind; // The type of the Element + int64_t _ordinal; // The ordinal value + int64_t _weight; // Weight of the file +}; + +/// \brief The Control class represents a control node in the InputGraph +class ControlNode : public InputElement { +public: + /// A control node could be of several types supported by InputGraph + /// Future kinds of Control node could be added + enum class ControlKind : uint8_t{ + Simple, // Represents a simple control node + Group // Represents a type associated with ControlNodes + }; + + ControlNode(ControlNode::ControlKind controlKind = + ControlNode::ControlKind::Simple, + int64_t _ordinal = -1) + : InputElement(InputElement::Kind::Control, _ordinal), + _controlKind(controlKind), _currentElementIndex(0), + _nextElementIndex(0) {} + + virtual ~ControlNode() {} + + /// \brief Return the kind of control node + virtual ControlNode::ControlKind controlKind() { return _controlKind; } + + /// \brief Process control start/exit + virtual bool processControlEnter() { return true; } + + /// \brief Process control start/exit + virtual bool processControlExit() { return true; } + + /// Process the input Elemenet + virtual bool processInputElement(std::unique_ptr element) = 0; + + /// \brief Casting support + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::Control; + } + + range elements() { + return make_range(_elements.begin(), _elements.end()); + } + + virtual void resetNextIndex() { + _currentElementIndex = _nextElementIndex = 0; + for (auto &elem : _elements) + elem->resetNextIndex(); + } + + virtual uint32_t getResolveState() const; + + virtual void setResolveState(uint32_t); + +protected: + ControlKind _controlKind; + InputGraph::InputElementVectorT _elements; + uint32_t _currentElementIndex; + uint32_t _nextElementIndex; +}; + +/// \brief Represents an Input file in the graph +/// +/// This class represents an input to the linker. It create the MemoryBuffer +/// lazily when needed based on the file path. It can also take a MemoryBuffer +/// directly. +class FileNode : public InputElement { +public: + FileNode(StringRef path, int64_t ordinal = -1); + + virtual ErrorOr getPath(const LinkingContext &) const { + return _path; + } + + // The saved input path thats used when a file is not found while + // trying to parse a file + StringRef getUserPath() const { return _path; } + + virtual ~FileNode() {} + + /// \brief Casting support + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::File; + } + + /// \brief create an error string for printing purposes + virtual std::string errStr(error_code errc) { + std::string msg = errc.message(); + Twine twine = Twine("Cannot open ") + _path + ": " + msg; + return twine.str(); + } + + /// \brief Get the list of files + range files() { + return make_range(_files.begin(), _files.end()); + } + + /// \brief number of files. + size_t numFiles() const { return _files.size(); } + + /// \brief add a file to the list of files + virtual void addFiles(InputGraph::FileVectorT files) { + for (auto &ai : files) + _files.push_back(std::move(ai)); + } + + /// \brief Reset the file index if the resolver needs to process + /// the node again. + virtual void resetNextIndex(); + + /// \brief Set the resolve state for the FileNode. + virtual void setResolveState(uint32_t resolveState) { + _resolveState = resolveState; + } + + /// \brief Retrieve the resolve state of the FileNode. + virtual uint32_t getResolveState() const { return _resolveState; } + +protected: + /// \brief Read the file into _buffer. + error_code getBuffer(StringRef filePath); + + StringRef _path; // The path of the Input file + InputGraph::FileVectorT _files; // A vector of lld File objects + std::unique_ptr _buffer; // Memory buffer to actual + // contents + uint32_t _resolveState; // The resolve state of the file + uint32_t _nextFileIndex; // The next file that would be processed by the + // resolver +}; + +/// \brief A Control node which contains a group of InputElements +/// This affects the resolver so that it resolves undefined symbols +/// in the group completely before looking at other input files that +/// follow the group +class Group : public ControlNode { +public: + Group(int64_t ordinal) + : ControlNode(ControlNode::ControlKind::Group, ordinal) {} + + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::Control; + } + + /// \brief Process input element and add it to the group + virtual bool processInputElement(std::unique_ptr element) { + _elements.push_back(std::move(element)); + return true; + } + + virtual ErrorOr getNextFile(); +}; + +/// \brief Represents Internal Input files +class SimpleFileNode : public InputElement { +public: + SimpleFileNode(StringRef path, int64_t ordinal = -1); + + virtual ErrorOr path(const LinkingContext &) const { + return _path; + } + + // The saved input path thats used when a file is not found while + // trying to parse a file + StringRef getUserPath() const { return _path; } + + virtual ~SimpleFileNode() {} + + /// \brief Casting support + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::SimpleFile; + } + + /// \brief Get the list of files + range files() { + return make_range(_files.begin(), _files.end()); + } + + /// \brief number of files. + size_t numFiles() const { return _files.size(); } + + /// \brief add a file to the list of files + virtual void appendInputFile(std::unique_ptr f) { + _files.push_back(std::move(f)); + } + + /// \brief add a file to the list of files + virtual void appendInputFiles(InputGraph::FileVectorT files) { + for (auto &ai : files) + _files.push_back(std::move(ai)); + } + + /// \brief validates the Input Element + virtual bool validate() { return true; } + + /// \brief Dump the Input Element + virtual bool dump(raw_ostream &) { return true; } + + /// \brief parse the input element + virtual error_code parse(const LinkingContext &, raw_ostream &) { + return error_code::success(); + } + + /// \brief Return the next File thats part of this node to the + /// resolver. + virtual ErrorOr getNextFile() { + if (_nextFileIndex == _files.size()) + return make_error_code(InputGraphError::no_more_files); + return *_files[_nextFileIndex++]; + } + + /// \brief Set the resolver state. + virtual void setResolveState(uint32_t resolveState) { + _resolveState = resolveState; + } + + /// \brief Retrieve the resolve state. + virtual uint32_t getResolveState() const { return _resolveState; } + + // Do nothing here. + virtual void resetNextIndex() {} + +protected: + StringRef _path; // A string associated with this file. + InputGraph::FileVectorT _files; // Vector of lld::File objects + uint32_t _nextFileIndex; // The next file that would be processed by the + // resolver + uint32_t _resolveState; // The resolve state associated with this Node +}; +} // namespace lld + +#endif // LLD_DRIVER_INPUT_GRAPH_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Instrumentation.h b/external/bsd/llvm/dist/lld/include/lld/Core/Instrumentation.h new file mode 100644 index 000000000..3059d0c56 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Instrumentation.h @@ -0,0 +1,133 @@ +//===- include/Core/Instrumentation.h - Instrumentation API ---------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Provide an Instrumentation API that optionally uses VTune interfaces. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_INSTRUMENTATION_H +#define LLD_CORE_INSTRUMENTATION_H + +#include "llvm/Support/Compiler.h" + +#include + +#ifdef LLD_HAS_VTUNE +# include +#endif + +namespace lld { +#ifdef LLD_HAS_VTUNE +/// \brief A unique global scope for instrumentation data. +/// +/// Domains last for the lifetime of the application and cannot be destroyed. +/// Multiple Domains created with the same name represent the same domain. +class Domain { + __itt_domain *_domain; + +public: + explicit Domain(const char *name) : _domain(__itt_domain_createA(name)) {} + + operator __itt_domain *() const { return _domain; } + __itt_domain *operator->() const { return _domain; } +}; + +/// \brief A global reference to a string constant. +/// +/// These are uniqued by the ITT runtime and cannot be deleted. They are not +/// specific to a domain. +/// +/// Prefer reusing a single StringHandle over passing a ntbs when the same +/// string will be used often. +class StringHandle { + __itt_string_handle *_handle; + +public: + StringHandle(const char *name) : _handle(__itt_string_handle_createA(name)) {} + + operator __itt_string_handle *() const { return _handle; } +}; + +/// \brief A task on a single thread. Nests within other tasks. +/// +/// Each thread has its own task stack and tasks nest recursively on that stack. +/// A task cannot transfer threads. +/// +/// SBRM is used to ensure task starts and ends are ballanced. The lifetime of +/// a task is either the liftime of this object, or until end is called. +class ScopedTask { + __itt_domain *_domain; + + ScopedTask(const ScopedTask &) LLVM_DELETED_FUNCTION; + ScopedTask &operator=(const ScopedTask &) LLVM_DELETED_FUNCTION; + +public: + /// \brief Create a task in Domain \p d named \p s. + ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) { + __itt_task_begin(d, __itt_null, __itt_null, s); + } + + ScopedTask(ScopedTask &&other) { + *this = std::move(other); + } + + ScopedTask &operator=(ScopedTask &&other) { + _domain = other._domain; + other._domain = nullptr; + return *this; + } + + /// \brief Prematurely end this task. + void end() { + if (_domain) + __itt_task_end(_domain); + _domain = nullptr; + } + + ~ScopedTask() { end(); } +}; + +/// \brief A specific point in time. Allows metadata to be associated. +class Marker { +public: + Marker(const Domain &d, const StringHandle &s) { + __itt_marker(d, __itt_null, s, __itt_scope_global); + } +}; +#else +class Domain { +public: + Domain(const char *name) {} +}; + +class StringHandle { +public: + StringHandle(const char *name) {} +}; + +class ScopedTask { +public: + ScopedTask(const Domain &d, const StringHandle &s) {} + void end() {} +}; + +class Marker { +public: + Marker(const Domain &d, const StringHandle &s) {} +}; +#endif + +inline const Domain &getDefaultDomain() { + static Domain domain("org.llvm.lld"); + return domain; +} +} // end namespace lld. + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/LLVM.h b/external/bsd/llvm/dist/lld/include/lld/Core/LLVM.h new file mode 100644 index 000000000..7f7a6529f --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/LLVM.h @@ -0,0 +1,92 @@ +//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file forward declares and imports various common LLVM datatypes that +// lld wants to use unqualified. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_LLVM_H +#define LLD_CORE_LLVM_H + +// This should be the only #include, force #includes of all the others on +// clients. +#include "llvm/ADT/Hashing.h" +#include "llvm/Support/Casting.h" + +#include + +namespace llvm { + // ADT's. + class StringRef; + class Twine; + class MemoryBuffer; + template class ArrayRef; + template class OwningPtr; + template class SmallString; + template class SmallVector; + template class SmallVectorImpl; + + template + struct SaveAndRestore; + + template + class ErrorOr; + + // Reference counting. + template class IntrusiveRefCntPtr; + template struct IntrusiveRefCntPtrInfo; + template class RefCountedBase; + class RefCountedBaseVPTR; + + class error_code; + class raw_ostream; + // TODO: DenseMap, ... +} + +namespace lld { + // Casting operators. + using llvm::isa; + using llvm::cast; + using llvm::dyn_cast; + using llvm::dyn_cast_or_null; + using llvm::cast_or_null; + + // ADT's. + using llvm::StringRef; + using llvm::Twine; + using llvm::MemoryBuffer; + using llvm::ArrayRef; + using llvm::OwningPtr; + using llvm::SmallString; + using llvm::SmallVector; + using llvm::SmallVectorImpl; + using llvm::SaveAndRestore; + using llvm::ErrorOr; + + // Reference counting. + using llvm::IntrusiveRefCntPtr; + using llvm::IntrusiveRefCntPtrInfo; + using llvm::RefCountedBase; + using llvm::RefCountedBaseVPTR; + + using llvm::error_code; + using llvm::raw_ostream; +} // end namespace clang. + +namespace std { +template <> struct hash { +public: + size_t operator()(const llvm::StringRef &s) const { + return llvm::hash_value(s); + } +}; +} + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/LinkingContext.h b/external/bsd/llvm/dist/lld/include/lld/Core/LinkingContext.h new file mode 100644 index 000000000..8584ce8c0 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/LinkingContext.h @@ -0,0 +1,378 @@ +//===- lld/Core/LinkingContext.h - Linker Target Info Interface -----------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_LINKING_CONTEXT_H +#define LLD_CORE_LINKING_CONTEXT_H + +#include "lld/Core/Error.h" +#include "lld/Core/InputGraph.h" +#include "lld/Core/LLVM.h" +#include "lld/Core/range.h" +#include "lld/Core/Reference.h" + +#include "lld/ReaderWriter/Reader.h" + +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + +namespace llvm { +class Triple; +} + +namespace lld { +class PassManager; +class File; +class Writer; +class InputGraph; +class InputElement; + +/// \brief The LinkingContext class encapsulates "what and how" to link. +/// +/// The base class LinkingContext contains the options needed by core linking. +/// Subclasses of LinkingContext have additional options needed by specific +/// Readers +/// and Writers. For example, ELFLinkingContext has methods that supplies +/// options +/// to the ELF Reader and Writer. +class LinkingContext { +public: + /// \brief The types of output file that the linker + /// creates. + enum class OutputFileType : uint8_t { + Default, // The default output type for this target + YAML, // The output type is set to YAML + Native // The output file format is Native (Atoms) + }; + + virtual ~LinkingContext(); + + /// \name Methods needed by core linking + /// @{ + + /// Name of symbol linker should use as "entry point" to program, + /// usually "main" or "start". + virtual StringRef entrySymbolName() const { return _entrySymbolName; } + + /// Whether core linking should remove Atoms not reachable by following + /// References from the entry point Atom or from all global scope Atoms + /// if globalsAreDeadStripRoots() is true. + bool deadStrip() const { return _deadStrip; } + + /// Only used if deadStrip() returns true. Means all global scope Atoms + /// should be marked live (along with all Atoms they reference). Usually + /// this method returns false for main executables, but true for dynamic + /// shared libraries. + bool globalsAreDeadStripRoots() const { + assert(_deadStrip && "only applicable when deadstripping enabled"); + return _globalsAreDeadStripRoots; + } + + /// Only used if deadStrip() returns true. This method returns the names + /// of DefinedAtoms that should be marked live (along with all Atoms they + /// reference). Only Atoms with scope scopeLinkageUnit or scopeGlobal can + /// be kept live using this method. + const std::vector &deadStripRoots() const { + return _deadStripRoots; + } + + /// Add the given symbol name to the dead strip root set. Only used if + /// deadStrip() returns true. + void addDeadStripRoot(StringRef symbolName) { + assert(_deadStrip && "only applicable when deadstripping enabled"); + assert(!symbolName.empty() && "Empty symbol cannot be a dead strip root"); + _deadStripRoots.push_back(symbolName); + } + + /// Archive files (aka static libraries) are normally lazily loaded. That is, + /// object files within an archive are only loaded and linked in, if the + /// object file contains a DefinedAtom which will replace an existing + /// UndefinedAtom. If this method returns true, core linking will also look + /// for archive members to replace existing tentative definitions in addition + /// to replacing undefines. Note: a "tentative definition" (also called a + /// "common" symbols) is a C (but not C++) concept. They are modeled in lld + /// as a DefinedAtom with merge() of mergeAsTentative. + bool searchArchivesToOverrideTentativeDefinitions() const { + return _searchArchivesToOverrideTentativeDefinitions; + } + + /// Normally core linking will turn a tentative definition into a real + /// definition if not replaced by a real DefinedAtom from some object file. + /// If this method returns true, core linking will search all supplied + /// dynamic shared libraries for symbol names that match remaining tentative + /// definitions. If any are found, the corresponding tentative definition + /// atom is replaced with SharedLibraryAtom. + bool searchSharedLibrariesToOverrideTentativeDefinitions() const { + return _searchSharedLibrariesToOverrideTentativeDefinitions; + } + + /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a + /// SharedLibraryAtom for the link to be successful. This method controls + /// whether core linking prints out a list of remaining UndefinedAtoms. + /// + /// \todo This should be a method core linking calls with a list of the + /// UndefinedAtoms so that different drivers can format the error message + /// as needed. + bool printRemainingUndefines() const { return _printRemainingUndefines; } + + /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a + /// SharedLibraryAtom for the link to be successful. This method controls + /// whether core linking considers remaining undefines to be an error. + bool allowRemainingUndefines() const { return _allowRemainingUndefines; } + + /// In the lld model, a SharedLibraryAtom is a proxy atom for something + /// that will be found in a dynamic shared library when the program runs. + /// A SharedLibraryAtom optionally contains the name of the shared library + /// in which to find the symbol name at runtime. Core linking may merge + /// two SharedLibraryAtom with the same name. If this method returns true, + /// when merging core linking will also verify that they both have the same + /// loadName() and if not print a warning. + /// + /// \todo This should be a method core linking calls so that drivers can + /// format the warning as needed. + bool warnIfCoalesableAtomsHaveDifferentLoadName() const { + return _warnIfCoalesableAtomsHaveDifferentLoadName; + } + + /// In C/C++ you can mark a function's prototype with + /// __attribute__((weak_import)) or __attribute__((weak)) to say the function + /// may not be available at runtime and/or build time and in which case its + /// address will evaluate to NULL. In lld this is modeled using the + /// UndefinedAtom::canBeNull() method. During core linking, UndefinedAtom + /// with the same name are automatically merged. If this method returns + /// true, core link also verfies that the canBeNull() value for merged + /// UndefinedAtoms are the same and warns if not. + /// + /// \todo This should be a method core linking calls so that drivers can + /// format the warning as needed. + bool warnIfCoalesableAtomsHaveDifferentCanBeNull() const { + return _warnIfCoalesableAtomsHaveDifferentCanBeNull; + } + + /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a + /// SharedLibraryAtom for the link to be successful. This method controls + /// whether core linking considers remaining undefines from the shared library + /// to be an error. + bool allowShlibUndefines() const { return _allowShlibUndefines; } + + /// If true, core linking will write the path to each input file to stdout + /// (i.e. llvm::outs()) as it is used. This is used to implement the -t + /// linker option. + /// + /// \todo This should be a method core linking calls so that drivers can + /// format the line as needed. + bool logInputFiles() const { return _logInputFiles; } + + /// Parts of LLVM use global variables which are bound to command line + /// options (see llvm::cl::Options). This method returns "command line" + /// options which are used to configure LLVM's command line settings. + /// For instance the -debug-only XXX option can be used to dynamically + /// trace different parts of LLVM and lld. + const std::vector &llvmOptions() const { return _llvmOptions; } + + /// \name Methods used by Drivers to configure TargetInfo + /// @{ + void setOutputPath(StringRef str) { _outputPath = str; } + + // Set the entry symbol name. You may also need to call addDeadStripRoot() for + // the symbol if your platform supports dead-stripping, so that the symbol + // will not be removed from the output. + void setEntrySymbolName(StringRef name) { + _entrySymbolName = name; + } + + void setDeadStripping(bool enable) { _deadStrip = enable; } + void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; } + void setSearchArchivesToOverrideTentativeDefinitions(bool search) { + _searchArchivesToOverrideTentativeDefinitions = search; + } + void setSearchSharedLibrariesToOverrideTentativeDefinitions(bool search) { + _searchSharedLibrariesToOverrideTentativeDefinitions = search; + } + void setWarnIfCoalesableAtomsHaveDifferentCanBeNull(bool warn) { + _warnIfCoalesableAtomsHaveDifferentCanBeNull = warn; + } + void setWarnIfCoalesableAtomsHaveDifferentLoadName(bool warn) { + _warnIfCoalesableAtomsHaveDifferentLoadName = warn; + } + void setPrintRemainingUndefines(bool print) { + _printRemainingUndefines = print; + } + void setAllowRemainingUndefines(bool allow) { + _allowRemainingUndefines = allow; + } + void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; } + void setLogInputFiles(bool log) { _logInputFiles = log; } + + void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); } + virtual void setInputGraph(std::unique_ptr inputGraph) { + _inputGraph = std::move(inputGraph); + } + virtual InputGraph &inputGraph() const { return *_inputGraph; } + + /// This method adds undefined symbols specified by the -u option to the to + /// the list of undefined symbols known to the linker. This option essentially + /// forces an undefined symbol to be create. You may also need to call + /// addDeadStripRoot() for the symbol if your platform supports dead + /// stripping, so that the symbol will not be removed from the output. + void addInitialUndefinedSymbol(StringRef symbolName) { + _initialUndefinedSymbols.push_back(symbolName); + } + + /// Iterators for symbols that appear on the command line + typedef std::vector StringRefVector; + typedef StringRefVector::iterator StringRefVectorIter; + typedef StringRefVector::const_iterator StringRefVectorConstIter; + + /// Create linker internal files containing atoms for the linker to include + /// during link. Flavors can override this function in their LinkingContext + /// to add more internal files. These internal files are positioned before + /// the actual input files. + virtual bool createInternalFiles(std::vector > &) const; + + /// Return the list of undefined symbols that are specified in the + /// linker command line, using the -u option. + range initialUndefinedSymbols() const { + return _initialUndefinedSymbols; + } + + /// After all set* methods are called, the Driver calls this method + /// to validate that there are no missing options or invalid combinations + /// of options. If there is a problem, a description of the problem + /// is written to the supplied stream. + /// + /// \returns true if there is an error with the current settings. + bool validate(raw_ostream &diagnostics); + + /// @} + /// \name Methods used by Driver::link() + /// @{ + + /// Returns the file system path to which the linked output should be written. + /// + /// \todo To support in-memory linking, we need an abstraction that allows + /// the linker to write to an in-memory buffer. + StringRef outputPath() const { return _outputPath; } + + /// Set the various output file types that the linker would + /// create + bool setOutputFileType(StringRef outputFileType) { + if (outputFileType.equals_lower("yaml")) + _outputFileType = OutputFileType::YAML; + else if (outputFileType.equals_lower("native")) + _outputFileType = OutputFileType::YAML; + else + return false; + return true; + } + + /// Returns the output file that that the linker needs to create + OutputFileType outputFileType() const { return _outputFileType; } + + /// Returns the YAML reader. + virtual Reader &getYAMLReader() const { return *_yamlReader; } + + /// Returns the LLD Native file format reader. + virtual Reader &getNativeReader() const { return *_nativeReader; } + + /// Return the default reader for the target + virtual Reader &getDefaultReader() const = 0; + + /// This method is called by core linking to give the Writer a chance + /// to add file format specific "files" to set of files to be linked. This is + /// how file format specific atoms can be added to the link. + virtual bool createImplicitFiles(std::vector > &) const; + + /// This method is called by core linking to build the list of Passes to be + /// run on the merged/linked graph of all input files. + virtual void addPasses(PassManager &pm); + + /// Calls through to the writeFile() method on the specified Writer. + /// + /// \param linkedFile This is the merged/linked graph of all input file Atoms. + virtual error_code writeFile(const File &linkedFile) const; + + /// nextFile returns the next file that needs to be processed by the resolver. + /// The LinkingContext's can override the default behavior to change the way + /// the resolver operates. This uses the currentInputElement. When there are + /// no more files to be processed an appropriate InputGraphError is + /// returned. Ordinals are assigned to files returned by nextFile, which means + /// ordinals would be assigned in the way files are resolved. + virtual ErrorOr nextFile(); + + /// Set the resolver state for the current Input element This is used by the + /// InputGraph to decide the next file that needs to be processed for various + /// types of nodes in the InputGraph. The resolver state is nothing but a + /// bitmask of various types of states that the resolver handles when adding + /// atoms. + virtual void setResolverState(uint32_t resolverState); + + /// Return the next ordinal and Increment it. + virtual uint64_t getNextOrdinalAndIncrement() const { return _nextOrdinal++; } + + /// @} + + /// \name Methods needed by YAML I/O and error messages to convert Kind values + /// to and from strings. + /// @{ + + /// Abstract method to parse a kind name string into an integral + /// Reference::Kind + virtual ErrorOr relocKindFromString(StringRef str) const = 0; + + /// Abstract method to return the name for a given integral + /// Reference::Kind. + virtual ErrorOr stringFromRelocKind(Reference::Kind k) const = 0; + + /// @} + +protected: + LinkingContext(); // Must be subclassed + + /// Abstract method to lazily instantiate the Writer. + virtual Writer &writer() const = 0; + + /// Method to create a internal file for the entry symbol + virtual std::unique_ptr createEntrySymbolFile() const; + + /// Method to create a internal file for an undefined symbol + virtual std::unique_ptr createUndefinedSymbolFile() const; + + StringRef _outputPath; + StringRef _entrySymbolName; + bool _deadStrip; + bool _globalsAreDeadStripRoots; + bool _searchArchivesToOverrideTentativeDefinitions; + bool _searchSharedLibrariesToOverrideTentativeDefinitions; + bool _warnIfCoalesableAtomsHaveDifferentCanBeNull; + bool _warnIfCoalesableAtomsHaveDifferentLoadName; + bool _printRemainingUndefines; + bool _allowRemainingUndefines; + bool _logInputFiles; + bool _allowShlibUndefines; + OutputFileType _outputFileType; + std::vector _deadStripRoots; + std::vector _llvmOptions; + std::unique_ptr _yamlReader; + std::unique_ptr _nativeReader; + StringRefVector _initialUndefinedSymbols; + std::unique_ptr _inputGraph; + mutable llvm::BumpPtrAllocator _allocator; + InputElement *_currentInputElement; + mutable uint64_t _nextOrdinal; + +private: + /// Validate the subclass bits. Only called by validate. + virtual bool validateImpl(raw_ostream &diagnostics) = 0; +}; +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Parallel.h b/external/bsd/llvm/dist/lld/include/lld/Core/Parallel.h new file mode 100644 index 000000000..b77a71ec6 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Parallel.h @@ -0,0 +1,271 @@ +//===- lld/Core/Parallel.h - Parallel utilities ---------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_PARALLEL_H +#define LLD_CORE_PARALLEL_H + +#include "lld/Core/Instrumentation.h" +#include "lld/Core/LLVM.h" +#include "lld/Core/range.h" + +#include "llvm/Support/MathExtras.h" + +#ifdef _MSC_VER +// Exceptions are disabled so this isn't defined, but concrt assumes it is. +namespace { +void *__uncaught_exception() { return nullptr; } +} +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#include +#include +#endif + +namespace lld { +/// \brief Allows one or more threads to wait on a potentially unknown number of +/// events. +/// +/// A latch starts at \p count. inc() increments this, and dec() decrements it. +/// All calls to sync() will block while the count is not 0. +/// +/// Calling dec() on a Latch with a count of 0 has undefined behaivor. +class Latch { + uint32_t _count; + mutable std::mutex _condMut; + mutable std::condition_variable _cond; + +public: + explicit Latch(uint32_t count = 0) : _count(count) {} + ~Latch() { sync(); } + + void inc() { + std::unique_lock lock(_condMut); + ++_count; + } + + void dec() { + std::unique_lock lock(_condMut); + if (--_count == 0) + _cond.notify_all(); + } + + void sync() const { + std::unique_lock lock(_condMut); + _cond.wait(lock, [&] { + return _count == 0; + }); + } +}; + +/// \brief An abstract class that takes closures and runs them asynchronously. +class Executor { +public: + virtual ~Executor() {} + virtual void add(std::function func) = 0; +}; + +/// \brief An implementation of an Executor that runs closures on a thread pool +/// in filo order. +class ThreadPoolExecutor : public Executor { +public: + explicit ThreadPoolExecutor(unsigned threadCount = + std::thread::hardware_concurrency()) + : _stop(false), _done(threadCount) { + // Spawn all but one of the threads in another thread as spawning threads + // can take a while. + std::thread([&, threadCount] { + for (std::size_t i = 1; i < threadCount; ++i) { + std::thread([=] { + work(); + }).detach(); + } + work(); + }).detach(); + } + + ~ThreadPoolExecutor() { + std::unique_lock lock(_mutex); + _stop = true; + lock.unlock(); + _cond.notify_all(); + // Wait for ~Latch. + } + + virtual void add(std::function f) { + std::unique_lock lock(_mutex); + _workStack.push(f); + lock.unlock(); + _cond.notify_one(); + } + +private: + void work() { + while (true) { + std::unique_lock lock(_mutex); + _cond.wait(lock, [&] { + return _stop || !_workStack.empty(); + }); + if (_stop) + break; + auto task = _workStack.top(); + _workStack.pop(); + lock.unlock(); + task(); + } + _done.dec(); + } + + std::atomic _stop; + std::stack> _workStack; + std::mutex _mutex; + std::condition_variable _cond; + Latch _done; +}; + +#ifdef _MSC_VER +/// \brief An Executor that runs tasks via ConcRT. +class ConcRTExecutor : public Executor { + struct Taskish { + Taskish(std::function task) : _task(task) {} + + std::function _task; + + static void run(void *p) { + Taskish *self = static_cast(p); + self->_task(); + concurrency::Free(self); + } + }; + +public: + virtual void add(std::function func) { + Concurrency::CurrentScheduler::ScheduleTask(Taskish::run, + new (concurrency::Alloc(sizeof(Taskish))) Taskish(func)); + } +}; + +inline Executor *getDefaultExecutor() { + static ConcRTExecutor exec; + return &exec; +} +#else +inline Executor *getDefaultExecutor() { + static ThreadPoolExecutor exec; + return &exec; +} +#endif + +/// \brief Allows launching a number of tasks and waiting for them to finish +/// either explicitly via sync() or implicitly on destruction. +class TaskGroup { + Latch _latch; + +public: + void spawn(std::function f) { + _latch.inc(); + getDefaultExecutor()->add([&, f] { + f(); + _latch.dec(); + }); + } + + void sync() const { _latch.sync(); } +}; + +#ifdef _MSC_VER +// Use ppl parallel_sort on Windows. +template +void parallel_sort( + RandomAccessIterator start, RandomAccessIterator end, + const Comp &comp = std::less< + typename std::iterator_traits::value_type>()) { + concurrency::parallel_sort(start, end, comp); +} +#else +namespace detail { +const ptrdiff_t minParallelSize = 1024; + +/// \brief Inclusive median. +template +RandomAccessIterator medianOf3(RandomAccessIterator start, + RandomAccessIterator end, const Comp &comp) { + RandomAccessIterator mid = start + (std::distance(start, end) / 2); + return comp(*start, *(end - 1)) + ? (comp(*mid, *(end - 1)) ? (comp(*start, *mid) ? mid : start) + : end - 1) + : (comp(*mid, *start) ? (comp(*(end - 1), *mid) ? mid : end - 1) + : start); +} + +template +void parallel_quick_sort(RandomAccessIterator start, RandomAccessIterator end, + const Comp &comp, TaskGroup &tg, size_t depth) { + // Do a sequential sort for small inputs. + if (std::distance(start, end) < detail::minParallelSize || depth == 0) { + std::sort(start, end, comp); + return; + } + + // Partition. + auto pivot = medianOf3(start, end, comp); + // Move pivot to end. + std::swap(*(end - 1), *pivot); + pivot = std::partition(start, end - 1, [end](decltype(*start) v) { + return v < *(end - 1); + }); + // Move pivot to middle of partition. + std::swap(*pivot, *(end - 1)); + + // Recurse. + tg.spawn([=, &tg] { + parallel_quick_sort(start, pivot, comp, tg, depth - 1); + }); + parallel_quick_sort(pivot + 1, end, comp, tg, depth - 1); +} +} + +template +void parallel_sort( + RandomAccessIterator start, RandomAccessIterator end, + const Comp &comp = std::less< + typename std::iterator_traits::value_type>()) { + TaskGroup tg; + detail::parallel_quick_sort(start, end, comp, tg, + llvm::Log2_64(std::distance(start, end)) + 1); +} +#endif + +template void parallel_sort(T *start, T *end) { + parallel_sort(start, end, std::less()); +} + +#ifdef _MSC_VER +// Use ppl parallel_for_each on Windows. +template +void parallel_for_each(Iterator begin, Iterator end, Func func) { + concurrency::parallel_for_each(begin, end, func); +} +#else +template +void parallel_for_each(Iterator begin, Iterator end, Func func) { + // TODO: Make this parallel. + std::for_each(begin, end, func); +} +#endif +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Pass.h b/external/bsd/llvm/dist/lld/include/lld/Core/Pass.h new file mode 100644 index 000000000..548a2a6d4 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Pass.h @@ -0,0 +1,118 @@ +//===------ Core/Pass.h - Base class for linker passes --------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_PASS_H +#define LLD_CORE_PASS_H + +#include "lld/Core/Atom.h" +#include "lld/Core/File.h" +#include "lld/Core/range.h" +#include "lld/Core/Reference.h" + +#include + +namespace lld { +class DefinedAtom; +class MutableFile; + +/// Once the core linking is done (which resolves references, coalesces atoms +/// and produces a complete Atom graph), the linker runs a series of passes +/// on the Atom graph. The graph is modeled as a File, which means the pass +/// has access to all the atoms and to File level attributes. Each pass does +/// a particular transformation to the Atom graph or to the File attributes. +/// +/// This is the abstract base class for all passes. A Pass does its +/// actual work in it perform() method. It can iterator over Atoms in the +/// graph using the *begin()/*end() atom iterator of the File. It can add +/// new Atoms to the graph using the File's addAtom() method. +class Pass { +public: + virtual ~Pass() { } + + /// Do the actual work of the Pass. + virtual void perform(std::unique_ptr &mergedFile) = 0; + +protected: + // Only subclassess can be instantiated. + Pass() { } +}; + +/// Pass for adding stubs (PLT entries) for calls to functions +/// outside the linkage unit. This class is subclassed by each +/// file format Writer which implements the pure virtual methods. +class StubsPass : public Pass { +public: + StubsPass() : Pass() {} + + /// Scans all Atoms looking for call-site uses of SharedLibraryAtoms + /// and transfroms the call-site to call a stub instead using the + /// helper methods below. + virtual void perform(std::unique_ptr &mergedFile); + + /// If true, the pass should use stubs for references + /// to shared library symbols. If false, the pass + /// will generate relocations on the text segment which the + /// runtime loader will use to patch the program at runtime. + virtual bool noTextRelocs() = 0; + + /// Returns whether the Reference kind is for a call site. The pass + /// uses this to find calls that need to be indirected through a stub. + virtual bool isCallSite(int32_t) = 0; + + /// Returns a file format specific atom for a stub/PLT entry which contains + /// instructions which jump to the specified atom. May be called multiple + /// times for the same target atom, in which case this method should return + /// the same stub atom. + virtual const DefinedAtom *getStub(const Atom &target) = 0; + + /// After the default implementation of perform() is done calling getStub(), + /// it will call this method to add all the stub (and support) atoms to the + /// master file object. + virtual void addStubAtoms(MutableFile &masterFile) = 0; +}; + +/// Pass for adding GOT entries for pointers to functions/data +/// outside the linkage unit. This class is subclassed by each +/// file format Writer which implements the pure virtual methods. +class GOTPass : public Pass { +public: + GOTPass() : Pass() {} + + /// Scans all Atoms looking for pointer to SharedLibraryAtoms + /// and transfroms them to a pointer to a GOT entry using the + /// helper methods below. + virtual void perform(std::unique_ptr &mergedFile); + + /// If true, the pass will use GOT entries for references + /// to shared library symbols. If false, the pass + /// will generate relocations on the text segment which the + /// runtime loader will use to patch the program at runtime. + virtual bool noTextRelocs() = 0; + + /// Returns whether the Reference kind is a pre-instantiated GOT access. + /// The default implementation of perform() uses this to figure out + /// what GOT entries to instantiate. + virtual bool isGOTAccess(int32_t, bool &canBypassGOT) = 0; + + /// The file format Writer needs to alter the reference kind from a + /// pre-instantiated GOT access to an actual access. If targetIsNowGOT is + /// true, the pass has instantiated a GOT atom and altered the reference's + /// target to point to that atom. If targetIsNowGOT is false, the pass + /// determined a GOT entry is not needed because the reference site can + /// directly access the target. + virtual void updateReferenceToGOT(const Reference*, bool targetIsNowGOT) = 0; + + /// Returns a file format specific atom for a GOT entry targeting + /// the specified atom. + virtual const DefinedAtom *makeGOTEntry(const Atom &target) = 0; +}; + +} // namespace lld + +#endif // LLD_CORE_PASS_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/PassManager.h b/external/bsd/llvm/dist/lld/include/lld/Core/PassManager.h new file mode 100644 index 000000000..4bf3e4967 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/PassManager.h @@ -0,0 +1,43 @@ +//===- lld/Core/PassManager.h - Manage linker passes ----------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_PASS_MANAGER_H +#define LLD_CORE_PASS_MANAGER_H + +#include "lld/Core/LLVM.h" +#include "lld/Core/Pass.h" + +#include +#include + +namespace lld { +class MutableFile; +class Pass; + +/// \brief Owns and runs a collection of passes. +/// +/// This class is currently just a container for passes and a way to run them. +/// +/// In the future this should handle timing pass runs, running parallel passes, +/// and validate/satisfy pass dependencies. +class PassManager { +public: + void add(std::unique_ptr pass) { + _passes.push_back(std::move(pass)); + } + + error_code runOnFile(std::unique_ptr &); + +private: + /// \brief Passes in the order they should run. + std::vector> _passes; +}; +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Reference.h b/external/bsd/llvm/dist/lld/include/lld/Core/Reference.h new file mode 100644 index 000000000..1af2e987d --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Reference.h @@ -0,0 +1,112 @@ +//===- Core/References.h - A Reference to Another Atom --------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_REFERENCES_H +#define LLD_CORE_REFERENCES_H + +#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/StringSwitch.h" + +namespace lld { +class Atom; + +/// +/// The linker has a Graph Theory model of linking. An object file is seen +/// as a set of Atoms with References to other Atoms. Each Atom is a node +/// and each Reference is an edge. +/// +/// For example if a function contains a call site to "malloc" 40 bytes into +/// the Atom, then the function Atom will have a Reference of: offsetInAtom=40, +/// kind=callsite, target=malloc, addend=0. +/// +/// Besides supporting traditional "relocations", References are also used +/// grouping atoms (group comdat), forcing layout (one atom must follow +/// another), marking data-in-code (jump tables or ARM constants), etc. +/// +class Reference { +public: + /// The meaning of positive kind values is architecture specific. + /// Negative kind values are architecture independent. + typedef int32_t Kind; + + enum { + kindInGroup = -3, + kindLayoutAfter = -2, + kindLayoutBefore = -1, + kindTargetLow = 0 + }; + + // A value to be added to the value of a target + typedef int64_t Addend; + + /// What sort of reference this is. + Kind kind() const { return _kind; } + + /// During linking, some optimizations may change the code gen and + /// hence the reference kind. + void setKind(Kind kind) { _kind = kind; }; + + virtual StringRef kindToString() const { + switch (kind()) { + case kindLayoutBefore: + return "layout-before"; + case kindLayoutAfter: + return "layout-after"; + case kindInGroup: + return "in-group"; + default: + return "unknown"; + } + } + + virtual int32_t stringToKind(StringRef kindString) const { + if (kindString == "in-group") + return kindInGroup; + else if (kindString == "layout-before") + return kindLayoutBefore; + else if (kindString == "layout-after") + return kindLayoutAfter; + assert(0 && "unknown relocation kind"); + return -1; + } + + /// If the reference is a fixup in the Atom, then this returns the + /// byte offset into the Atom's content to do the fix up. + virtual uint64_t offsetInAtom() const = 0; + + /// If the reference is an edge to another Atom, then this returns the + /// other Atom. Otherwise, it returns nullptr. + virtual const Atom *target() const = 0; + + /// During linking, the linker may merge graphs which coalesces some nodes + /// (i.e. Atoms). To switch the target of a reference, this method is called. + virtual void setTarget(const Atom *) = 0; + + /// Some relocations require a symbol and a value (e.g. foo + 4). + virtual Addend addend() const = 0; + + /// During linking, some optimzations may change addend value. + virtual void setAddend(Addend) = 0; + +protected: + /// Atom is an abstract base class. Only subclasses can access constructor. + Reference() {} + + /// The memory for Reference objects is always managed by the owning File + /// object. Therefore, no one but the owning File object should call + /// delete on an Reference. In fact, some File objects may bulk allocate + /// an array of References, so they cannot be individually deleted by anyone. + virtual ~Reference() {} + + Kind _kind; +}; + +} // namespace lld + +#endif // LLD_CORE_REFERENCES_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/Resolver.h b/external/bsd/llvm/dist/lld/include/lld/Core/Resolver.h new file mode 100644 index 000000000..dafe7470b --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/Resolver.h @@ -0,0 +1,128 @@ +//===- Core/Resolver.h - Resolves Atom References -------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_RESOLVER_H +#define LLD_CORE_RESOLVER_H + +#include "lld/Core/File.h" +#include "lld/Core/SharedLibraryFile.h" +#include "lld/Core/SymbolTable.h" + +#include "llvm/ADT/DenseSet.h" + +#include +#include + +namespace lld { + +class Atom; +class LinkingContext; + +/// \brief The Resolver is responsible for merging all input object files +/// and producing a merged graph. +class Resolver { +public: + enum ResolverState { + StateNoChange = 0, // The default resolver state + StateNewDefinedAtoms = 1, // New defined atoms were added + StateNewUndefinedAtoms = 2, // New undefined atoms were added + StateNewSharedLibraryAtoms = 4, // New shared library atoms were added + StateNewAbsoluteAtoms = 8 // New absolute atoms were added + }; + + Resolver(LinkingContext &context) + : _context(context), _symbolTable(context), + _result(new MergedFile(context)), _haveLLVMObjs(false), + _addToFinalSection(false) {} + + virtual ~Resolver() {} + + // InputFiles::Handler methods + virtual void doDefinedAtom(const DefinedAtom&); + virtual void doUndefinedAtom(const UndefinedAtom&); + virtual void doSharedLibraryAtom(const SharedLibraryAtom &); + virtual void doAbsoluteAtom(const AbsoluteAtom &); + virtual void doFile(const File&); + + // Handle files, this adds atoms from the current file thats + // being processed by the resolver + virtual void handleFile(const File &); + + // Handle an archive library file. + virtual void handleArchiveFile(const File &); + + // Handle a shared library file. + virtual void handleSharedLibrary(const File &); + + /// @brief do work of merging and resolving and return list + bool resolve(); + + std::unique_ptr resultFile() { return std::move(_result); } + +private: + typedef std::function UndefCallback; + + /// \brief The main function that iterates over the files to resolve + bool resolveUndefines(); + void updateReferences(); + void deadStripOptimize(); + bool checkUndefines(bool final); + void removeCoalescedAwayAtoms(); + void checkDylibSymbolCollisions(); + void linkTimeOptimize(); + void tweakAtoms(); + void forEachUndefines(UndefCallback callback, bool searchForOverrides); + + void markLive(const Atom &atom); + void addAtoms(const std::vector&); + + class MergedFile : public MutableFile { + public: + MergedFile(const LinkingContext &context) + : MutableFile(context, "") {} + + virtual const atom_collection &defined() const { + return _definedAtoms; + } + virtual const atom_collection& undefined() const { + return _undefinedAtoms; + } + virtual const atom_collection& sharedLibrary() const { + return _sharedLibraryAtoms; + } + virtual const atom_collection& absolute() const { + return _absoluteAtoms; + } + + void addAtoms(std::vector& atoms); + + virtual void addAtom(const Atom& atom); + virtual DefinedAtomRange definedAtoms(); + + private: + atom_collection_vector _definedAtoms; + atom_collection_vector _undefinedAtoms; + atom_collection_vector _sharedLibraryAtoms; + atom_collection_vector _absoluteAtoms; + }; + + LinkingContext &_context; + SymbolTable _symbolTable; + std::vector _atoms; + std::set _deadStripRoots; + std::vector _atomsWithUnresolvedReferences; + llvm::DenseSet _liveAtoms; + std::unique_ptr _result; + bool _haveLLVMObjs; + bool _addToFinalSection; +}; + +} // namespace lld + +#endif // LLD_CORE_RESOLVER_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/STDExtras.h b/external/bsd/llvm/dist/lld/include/lld/Core/STDExtras.h new file mode 100644 index 000000000..a22e117d0 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/STDExtras.h @@ -0,0 +1,33 @@ +//===- lld/Core/STDExtra.h - Helpers for the stdlib -----------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_STD_EXTRA_H +#define LLD_CORE_STD_EXTRA_H + +namespace lld { +/// \brief Deleter for smart pointers that only calls the destructor. Memory is +/// managed elsewhere. A common use of this is for things allocated with a +/// BumpPtrAllocator. +template +struct destruct_delete { + void operator ()(T *ptr) { + ptr->~T(); + } +}; + +// Sadly VS 2012 doesn't support template aliases. +// template +// using unique_bump_ptr = std::unique_ptr>; + +#define LLD_UNIQUE_BUMP_PTR(...) \ + std::unique_ptr<__VA_ARGS__, destruct_delete<__VA_ARGS__>> + +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryAtom.h b/external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryAtom.h new file mode 100644 index 000000000..76a7d0a2f --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryAtom.h @@ -0,0 +1,57 @@ +//===- Core/SharedLibraryAtom.h - A Shared Library Atom -------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_SHARED_LIBRARY_ATOM_H +#define LLD_CORE_SHARED_LIBRARY_ATOM_H + +#include "lld/Core/Atom.h" + +namespace llvm { + class StringRef; +} + +namespace lld { + +/// A SharedLibraryAtom has no content. +/// It exists to represent a symbol which will be bound at runtime. +class SharedLibraryAtom : public Atom { +public: + enum class Type : uint32_t { + Unknown, + Code, + Data, + }; + + /// Returns shared library name used to load it at runtime. + /// On linux that is the DT_NEEDED name. + /// On Darwin it is the LC_DYLIB_LOAD dylib name. + /// On Windows it is the DLL name that to be referred from .idata section. + virtual StringRef loadName() const = 0; + + /// Returns if shared library symbol can be missing at runtime and if + /// so the loader should silently resolve address of symbol to be nullptr. + virtual bool canBeNullAtRuntime() const = 0; + + virtual Type type() const = 0; + + virtual uint64_t size() const = 0; + + static inline bool classof(const Atom *a) { + return a->definition() == definitionSharedLibrary; + } + static inline bool classof(const SharedLibraryAtom *) { return true; } + +protected: + SharedLibraryAtom() : Atom(definitionSharedLibrary) {} + virtual ~SharedLibraryAtom() {} +}; + +} // namespace lld + +#endif // LLD_CORE_SHARED_LIBRARY_ATOM_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryFile.h b/external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryFile.h new file mode 100644 index 000000000..bdbe1f4d2 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/SharedLibraryFile.h @@ -0,0 +1,42 @@ +//===- Core/SharedLibraryFile.h - Models shared libraries as Atoms --------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_SHARED_LIBRARY_FILE_H +#define LLD_CORE_SHARED_LIBRARY_FILE_H + +#include "lld/Core/File.h" +#include "lld/Core/SharedLibraryAtom.h" + +namespace lld { + +/// +/// The SharedLibraryFile subclass of File is used to represent dynamic +/// shared libraries being linked against. +/// +class SharedLibraryFile : public File { +public: + virtual ~SharedLibraryFile() {} + + static inline bool classof(const File *f) { + return f->kind() == kindSharedLibrary; + } + + /// Check if the shared library exports a symbol with the specified name. + /// If so, return a SharedLibraryAtom which represents that exported + /// symbol. Otherwise return nullptr. + virtual const SharedLibraryAtom *exports(StringRef name, + bool dataSymbolOnly) const = 0; +protected: + /// only subclasses of SharedLibraryFile can be instantiated + explicit SharedLibraryFile(StringRef path) : File(path, kindSharedLibrary) {} +}; + +} // namespace lld + +#endif // LLD_CORE_SHARED_LIBRARY_FILE_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/SymbolTable.h b/external/bsd/llvm/dist/lld/include/lld/Core/SymbolTable.h new file mode 100644 index 000000000..a9d7a1e8a --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/SymbolTable.h @@ -0,0 +1,110 @@ +//===- Core/SymbolTable.h - Main Symbol Table -----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_SYMBOL_TABLE_H +#define LLD_CORE_SYMBOL_TABLE_H + +#include "lld/Core/LLVM.h" + +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" + +#include +#include +#include + +namespace lld { + +class AbsoluteAtom; +class Atom; +class DefinedAtom; +class LinkingContext; +class ResolverOptions; +class SharedLibraryAtom; +class UndefinedAtom; + +/// \brief The SymbolTable class is responsible for coalescing atoms. +/// +/// All atoms coalescable by-name or by-content should be added. +/// The method replacement() can be used to find the replacement atom +/// if an atom has been coalesced away. +class SymbolTable { +public: + explicit SymbolTable(const LinkingContext &); + + /// @brief add atom to symbol table + void add(const DefinedAtom &); + + /// @brief add atom to symbol table + void add(const UndefinedAtom &); + + /// @brief add atom to symbol table + void add(const SharedLibraryAtom &); + + /// @brief add atom to symbol table + void add(const AbsoluteAtom &); + + /// @brief checks if name is in symbol table and if so atom is not + /// UndefinedAtom + bool isDefined(StringRef sym); + + /// @brief returns atom in symbol table for specified name (or nullptr) + const Atom *findByName(StringRef sym); + + /// @brief returns vector of remaining UndefinedAtoms + void undefines(std::vector&); + + /// returns vector of tentative definitions + void tentativeDefinitions(std::vector &); + + /// @brief count of by-name entries in symbol table + unsigned int size(); + + /// @brief add atom to replacement table + void addReplacement(const Atom *replaced, const Atom *replacement); + + /// @brief if atom has been coalesced away, return replacement, else return atom + const Atom *replacement(const Atom *); + +private: + typedef llvm::DenseMap AtomToAtom; + + struct StringRefMappingInfo { + static StringRef getEmptyKey() { return StringRef(); } + static StringRef getTombstoneKey() { return StringRef(" ", 0); } + static unsigned getHashValue(StringRef const val) { + return llvm::HashString(val); } + static bool isEqual(StringRef const lhs, + StringRef const rhs) { return lhs.equals(rhs); } + }; + typedef llvm::DenseMap NameToAtom; + + struct AtomMappingInfo { + static const DefinedAtom * getEmptyKey() { return nullptr; } + static const DefinedAtom * getTombstoneKey() { return (DefinedAtom*)(-1); } + static unsigned getHashValue(const DefinedAtom * const Val); + static bool isEqual(const DefinedAtom * const LHS, + const DefinedAtom * const RHS); + }; + typedef llvm::DenseSet AtomContentSet; + + void addByName(const Atom &); + void addByContent(const DefinedAtom &); + + const LinkingContext &_context; + AtomToAtom _replacedAtoms; + NameToAtom _nameTable; + AtomContentSet _contentTable; +}; + +} // namespace lld + +#endif // LLD_CORE_SYMBOL_TABLE_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/TODO.txt b/external/bsd/llvm/dist/lld/include/lld/Core/TODO.txt new file mode 100644 index 000000000..8888c763e --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/TODO.txt @@ -0,0 +1,17 @@ +include/lld/Core +~~~~~~~~~~~~~~~~ + +* The native/yaml reader/writer interfaces should be changed to return + an explanatory string if there is an error. The existing error_code + abstraction only works for returning low level OS errors. It does not + work for describing formatting issues. + +* We need to design a diagnostics interface. It would be nice to share code + with Clang_ where possible. + +* We need to add more attributes to File. In particular, we need cpu + and OS information (like target triples). We should also provide explicit + support for `LLVM IR module flags metadata`__. + +.. __: http://llvm.org/docs/LangRef.html#module_flags +.. _Clang: http://clang.llvm.org/docs/InternalsManual.html#Diagnostics diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/UndefinedAtom.h b/external/bsd/llvm/dist/lld/include/lld/Core/UndefinedAtom.h new file mode 100644 index 000000000..5bb14e8c0 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/UndefinedAtom.h @@ -0,0 +1,74 @@ +//===- Core/UndefinedAtom.h - An Undefined Atom ---------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_UNDEFINED_ATOM_H +#define LLD_CORE_UNDEFINED_ATOM_H + +#include "lld/Core/Atom.h" + +namespace lld { + +/// An UndefinedAtom has no content. +/// It exists as a place holder for a future atom. +class UndefinedAtom : public Atom { +public: + /// Whether this undefined symbol needs to be resolved, + /// or whether it can just evaluate to nullptr. + /// This concept is often called "weak", but that term + /// is overloaded to mean other things too. + enum CanBeNull { + /// Normal symbols must be resolved at build time + canBeNullNever, + + /// This symbol can be missing at runtime and will evalute to nullptr. + /// That is, the static linker still must find a definition (usually + /// is some shared library), but at runtime, the dynamic loader + /// will allow the symbol to be missing and resolved to nullptr. + /// + /// On Darwin this is generated using a function prototype with + /// __attribute__((weak_import)). + /// On linux this is generated using a function prototype with + /// __attribute__((weak)). + /// On Windows this feature is not supported. + canBeNullAtRuntime, + + /// This symbol can be missing at build time. + /// That is, the static linker will not error if a definition for + /// this symbol is not found at build time. Instead, the linker + /// will build an executable that lets the dynamic loader find the + /// symbol at runtime. + /// This feature is not supported on Darwin nor Windows. + /// On linux this is generated using a function prototype with + /// __attribute__((weak)). + canBeNullAtBuildtime + }; + + virtual CanBeNull canBeNull() const = 0; + + static inline bool classof(const Atom *a) { + return a->definition() == definitionUndefined; + } + static inline bool classof(const UndefinedAtom *) { return true; } + + /// Returns an undefined atom if this undefined symbol has a synonym. This is + /// mainly used in COFF. In COFF, an unresolved external symbol can have up to + /// one optional name (sym2) in addition to its regular name (sym1). If a + /// definition of sym1 exists, sym1 is resolved normally. Otherwise, all + /// references to sym1 refer to sym2 instead. In that case sym2 must be + /// resolved, or link will fail. + virtual const UndefinedAtom *fallback() const { return nullptr; } + +protected: + UndefinedAtom() : Atom(definitionUndefined) {} + virtual ~UndefinedAtom() {} +}; + +} // namespace lld + +#endif // LLD_CORE_UNDEFINED_ATOM_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Core/range.h b/external/bsd/llvm/dist/lld/include/lld/Core/range.h new file mode 100644 index 000000000..e4b6e2574 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Core/range.h @@ -0,0 +1,739 @@ +//===-- lld/Core/range.h - Iterator ranges ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Iterator range type based on c++1y range proposal. +/// +/// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_RANGE_H +#define LLD_CORE_RANGE_H + +#include "llvm/Support/Compiler.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace lld { +// Nothing in this namespace is part of the exported interface. +namespace detail { +using std::begin; +using std::end; +/// Used as the result type of undefined functions. +struct undefined {}; + +template class begin_result { + template static auto check(T &&t) -> decltype(begin(t)); + static undefined check(...); +public: + typedef decltype(check(std::declval())) type; +}; + +template class end_result { + template static auto check(T &&t) -> decltype(end(t)); + static undefined check(...); +public: + typedef decltype(check(std::declval())) type; +}; + +// Things that begin and end work on, in compatible ways, are +// ranges. [stmt.ranged] +template +struct is_range : std::is_same::type, + typename detail::end_result::type> {}; + +// This currently requires specialization and doesn't work for +// detecting \c range<>s or iterators. We should add +// \c contiguous_iterator_tag to fix that. +template struct is_contiguous_range : std::false_type {}; +template +struct is_contiguous_range : is_contiguous_range {}; +template +struct is_contiguous_range : is_contiguous_range {}; +template +struct is_contiguous_range : is_contiguous_range {}; + +template +struct is_contiguous_range : std::true_type {}; +template +struct is_contiguous_range : std::true_type {}; +template +struct is_contiguous_range > : std::true_type {}; +template +struct is_contiguous_range< + std::basic_string > : std::true_type {}; +template +struct is_contiguous_range > : std::true_type {}; + +// Removes cv qualifiers from all levels of a multi-level pointer +// type, not just the type level. +template struct remove_all_cv_ptr { + typedef T type; +}; +template struct remove_all_cv_ptr { + typedef typename remove_all_cv_ptr::type *type; +}; +template struct remove_all_cv_ptr { + typedef typename remove_all_cv_ptr::type type; +}; +template struct remove_all_cv_ptr { + typedef typename remove_all_cv_ptr::type type; +}; +template struct remove_all_cv_ptr { + typedef typename remove_all_cv_ptr::type type; +}; + +template +struct conversion_preserves_array_indexing : std::false_type {}; + +template +struct conversion_preserves_array_indexing : std::integral_constant< + bool, std::is_convertible::value && + std::is_same::type, + typename remove_all_cv_ptr::type>::value> {}; + +template +LLVM_CONSTEXPR auto adl_begin(T &&t) -> decltype(begin(t)) { + return begin(std::forward(t)); +} + +template LLVM_CONSTEXPR auto adl_end(T &&t) -> decltype(end(t)) { + return end(std::forward(t)); +} +} // end namespace detail + +/// A \c std::range represents a half-open iterator range +/// built from two iterators, \c 'begin', and \c 'end'. If \c end is +/// not reachable from \c begin, the behavior is undefined. +/// +/// The mutability of elements of the range is controlled by the +/// Iterator argument. Instantiate +/// range<Foo::iterator> or +/// range<T*>, or call +/// make_range(non_const_container), and you +/// get a mutable range. Instantiate +/// range<Foo::const_iterator> or +/// rangeT*>, or call +/// make_range(const_container), and you get a +/// constant range. +/// +/// \todo Inherit from std::pair? +/// +/// \todo This interface contains some functions that could be +/// provided as free algorithms rather than member functions, and all +/// of the pop_*() functions could be replaced by \c +/// slice() at the cost of some extra iterator copies. This makes +/// them more awkward to use, but makes it easier for users to write +/// their own types that follow the same interface. On the other hand, +/// a \c range_facade could be provided to help users write new +/// ranges, and it could provide the members. Such functions are +/// marked with a note in their documentation. (Of course, all of +/// these member functions could be provided as free functions using +/// the iterator access methods, but one goal here is to allow people +/// to program without touching iterators at all.) +template class range { + Iterator begin_, end_; +public: + /// \name types + /// @{ + + /// The iterator category of \c Iterator. + /// \todo Consider defining range categories. If they don't add + /// anything over the corresponding iterator categories, then + /// they're probably not worth defining. + typedef typename std::iterator_traits< + Iterator>::iterator_category iterator_category; + /// The type of elements of the range. Not cv-qualified. + typedef typename std::iterator_traits::value_type value_type; + /// The type of the size of the range and offsets within the range. + typedef typename std::iterator_traits< + Iterator>::difference_type difference_type; + /// The return type of element access methods: \c front(), \c back(), etc. + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::pointer pointer; + /// @} + + /// \name constructors + /// @{ + + /// Creates a range of default-constructed (not + /// value-initialized) iterators. For most \c Iterator types, this + /// will be an invalid range. + range() : begin_(), end_() {} + + /// \pre \c end is reachable from \c begin. + /// \post this->begin() == begin && this->end() == end + LLVM_CONSTEXPR range(Iterator begin, Iterator end) + : begin_(begin), end_(end) {} + + /// \par Participates in overload resolution if: + /// - \c Iterator is not a pointer type, + /// - \c begin(r) and \c end(r) return the same type, and + /// - that type is convertible to \c Iterator. + /// + /// \todo std::begin and std::end are overloaded between T& and + /// const T&, which means that if a container has only a non-const + /// begin or end method, then it's ill-formed to pass an rvalue to + /// the free function. To avoid that problem, we don't use + /// std::forward<> here, so begin() and end() are always called with + /// an lvalue. Another option would be to insist that rvalue + /// arguments to range() must have const begin() and end() methods. + template LLVM_CONSTEXPR range( + R &&r, + typename std::enable_if< + !std::is_pointer::value && + detail::is_range::value && + std::is_convertible::type, + Iterator>::value>::type* = 0) + : begin_(detail::adl_begin(r)), end_(detail::adl_end(r)) {} + + /// This constructor creates a \c range from any range with + /// contiguous iterators. Because dereferencing a past-the-end + /// iterator can be undefined behavior, empty ranges get initialized + /// with \c nullptr rather than \c &*begin(). + /// + /// \par Participates in overload resolution if: + /// - \c Iterator is a pointer type \c T*, + /// - \c begin(r) and \c end(r) return the same type, + /// - elements \c i of that type satisfy the invariant + /// &*(i + N) == (&*i) + N, and + /// - The result of &*begin() is convertible to \c T* + /// using only qualification conversions [conv.qual] (since + /// pointer conversions stop the pointer from pointing to an + /// array element). + /// + /// \todo The &*(i + N) == (&*i) + N invariant is + /// currently impossible to check for user-defined types. We need a + /// \c contiguous_iterator_tag to let users assert it. + template LLVM_CONSTEXPR range( + R &&r, + typename std::enable_if< + std::is_pointer::value && + detail::is_contiguous_range::value + // MSVC returns false for this in this context, but not if we lift it out of the + // constructor. +#ifndef _MSC_VER + && detail::conversion_preserves_array_indexing< + decltype(&*detail::adl_begin(r)), Iterator>::value +#endif + >::type* = 0) + : begin_((detail::adl_begin(r) == detail::adl_end(r) && + !std::is_pointer::value) + // For non-pointers, &*begin(r) is only defined behavior + // if there's an element there. Otherwise, use nullptr + // since the user can't dereference it anyway. This _is_ + // detectable. + ? nullptr : &*detail::adl_begin(r)), + end_(begin_ + (detail::adl_end(r) - detail::adl_begin(r))) {} + + /// @} + + /// \name iterator access + /// @{ + LLVM_CONSTEXPR Iterator begin() const { return begin_; } + LLVM_CONSTEXPR Iterator end() const { return end_; } + /// @} + + /// \name element access + /// @{ + + /// \par Complexity: + /// O(1) + /// \pre \c !empty() + /// \returns a reference to the element at the front of the range. + LLVM_CONSTEXPR reference front() const { return *begin(); } + + /// \par Ill-formed unless: + /// \c iterator_category is convertible to \c + /// std::bidirectional_iterator_tag. + /// + /// \par Complexity: + /// O(2) (Involves copying and decrementing an iterator, so not + /// quite as cheap as \c front()) + /// + /// \pre \c !empty() + /// \returns a reference to the element at the front of the range. + LLVM_CONSTEXPR reference back() const { + static_assert( + std::is_convertible::value, + "Can only retrieve the last element of a bidirectional range."); + using std::prev; + return *prev(end()); + } + + /// This method is drawn from scripting language indexing. It + /// indexes std::forward from the beginning of the range if the argument + /// is positive, or backwards from the end of the array if the + /// argument is negative. + /// + /// \par Ill-formed unless: + /// \c iterator_category is convertible to \c + /// std::random_access_iterator_tag. + /// + /// \par Complexity: + /// O(1) + /// + /// \pre abs(index) < size() || index == -size() + /// + /// \returns if index >= 0, a reference to the + /// index'th element in the range. Otherwise, a + /// reference to the size()+index'th element. + LLVM_CONSTEXPR reference operator[](difference_type index) const { + static_assert(std::is_convertible::value, + "Can only index into a random-access range."); + // Less readable construction for constexpr support. + return index < 0 ? end()[index] + : begin()[index]; + } + /// @} + + /// \name size + /// @{ + + /// \par Complexity: + /// O(1) + /// \returns \c true if the range contains no elements. + LLVM_CONSTEXPR bool empty() const { return begin() == end(); } + + /// \par Ill-formed unless: + /// \c iterator_category is convertible to + /// \c std::forward_iterator_tag. + /// + /// \par Complexity: + /// O(1) if \c iterator_category is convertible to \c + /// std::random_access_iterator_tag. O(size()) + /// otherwise. + /// + /// \returns the number of times \c pop_front() can be called before + /// \c empty() becomes true. + LLVM_CONSTEXPR difference_type size() const { + static_assert(std::is_convertible::value, + "Calling size on an input range would destroy the range."); + return dispatch_size(iterator_category()); + } + /// @} + + /// \name traversal from the beginning of the range + /// @{ + + /// Advances the beginning of the range by one element. + /// \pre \c !empty() + void pop_front() { ++begin_; } + + /// Advances the beginning of the range by \c n elements. + /// + /// \par Complexity: + /// O(1) if \c iterator_category is convertible to \c + /// std::random_access_iterator_tag, O(n) otherwise. + /// + /// \pre n >= 0, and there must be at least \c n + /// elements in the range. + void pop_front(difference_type n) { advance(begin_, n); } + + /// Advances the beginning of the range by at most \c n elements, + /// stopping if the range becomes empty. A negative argument causes + /// no change. + /// + /// \par Complexity: + /// O(1) if \c iterator_category is convertible to \c + /// std::random_access_iterator_tag, O(min(n, + /// #-elements-in-range)) otherwise. + /// + /// \note Could be provided as a free function with little-to-no + /// loss in efficiency. + void pop_front_upto(difference_type n) { + advance_upto(begin_, std::max(0, n), end_, + iterator_category()); + } + + /// @} + + /// \name traversal from the end of the range + /// @{ + + /// Moves the end of the range earlier by one element. + /// + /// \par Ill-formed unless: + /// \c iterator_category is convertible to + /// \c std::bidirectional_iterator_tag. + /// + /// \par Complexity: + /// O(1) + /// + /// \pre \c !empty() + void pop_back() { + static_assert(std::is_convertible::value, + "Can only access the end of a bidirectional range."); + --end_; + } + + /// Moves the end of the range earlier by \c n elements. + /// + /// \par Ill-formed unless: + /// \c iterator_category is convertible to + /// \c std::bidirectional_iterator_tag. + /// + /// \par Complexity: + /// O(1) if \c iterator_category is convertible to \c + /// std::random_access_iterator_tag, O(n) otherwise. + /// + /// \pre n >= 0, and there must be at least \c n + /// elements in the range. + void pop_back(difference_type n) { + static_assert(std::is_convertible::value, + "Can only access the end of a bidirectional range."); + advance(end_, -n); + } + + /// Moves the end of the range earlier by min(n, + /// size()) elements. A negative argument causes no change. + /// + /// \par Ill-formed unless: + /// \c iterator_category is convertible to + /// \c std::bidirectional_iterator_tag. + /// + /// \par Complexity: + /// O(1) if \c iterator_category is convertible to \c + /// std::random_access_iterator_tag, O(min(n, + /// #-elements-in-range)) otherwise. + /// + /// \note Could be provided as a free function with little-to-no + /// loss in efficiency. + void pop_back_upto(difference_type n) { + static_assert(std::is_convertible::value, + "Can only access the end of a bidirectional range."); + advance_upto(end_, -std::max(0, n), begin_, + iterator_category()); + } + + /// @} + + /// \name creating derived ranges + /// @{ + + /// Divides the range into two pieces at \c index, where a positive + /// \c index represents an offset from the beginning of the range + /// and a negative \c index represents an offset from the end. + /// range[index] is the first element in the second + /// piece. If index >= size(), the second piece + /// will be empty. If index < -size(), the first + /// piece will be empty. + /// + /// \par Ill-formed unless: + /// \c iterator_category is convertible to + /// \c std::forward_iterator_tag. + /// + /// \par Complexity: + /// - If \c iterator_category is convertible to \c + /// std::random_access_iterator_tag: O(1) + /// - Otherwise, if \c iterator_category is convertible to \c + /// std::bidirectional_iterator_tag, \c abs(index) iterator increments + /// or decrements + /// - Otherwise, if index >= 0, \c index iterator + /// increments + /// - Otherwise, size() + (size() + index) + /// iterator increments. + /// + /// \returns a pair of adjacent ranges. + /// + /// \post + /// - result.first.size() == min(index, this->size()) + /// - result.first.end() == result.second.begin() + /// - result.first.size() + result.second.size() == + /// this->size() + /// + /// \todo split() could take an arbitrary number of indices and + /// return an N+1-element \c tuple<>. This is tricky to + /// implement with negative indices in the optimal number of + /// increments or decrements for a bidirectional iterator, but it + /// should be possible. Do we want it? + std::pair split(difference_type index) const { + static_assert( + std::is_convertible::value, + "Calling split on a non-std::forward range would return a useless " + "first result."); + if (index >= 0) { + range second = *this; + second.pop_front_upto(index); + return make_pair(range(begin(), second.begin()), second); + } else { + return dispatch_split_neg(index, iterator_category()); + } + } + + /// \returns A sub-range from \c start to \c stop (not including \c + /// stop, as usual). \c start and \c stop are interpreted as for + /// operator[], with negative values offsetting from + /// the end of the range. Omitting the \c stop argument makes the + /// sub-range continue to the end of the original range. Positive + /// arguments saturate to the end of the range, and negative + /// arguments saturate to the beginning. If \c stop is before \c + /// start, returns an empty range beginning and ending at \c start. + /// + /// \par Ill-formed unless: + /// \c iterator_category is convertible to + /// \c std::forward_iterator_tag. + /// + /// \par Complexity: + /// - If \c iterator_category is convertible to \c + /// std::random_access_iterator_tag: O(1) + /// - Otherwise, if \c iterator_category is convertible to \c + /// std::bidirectional_iterator_tag, at most min(abs(start), + /// size()) + min(abs(stop), size()) iterator + /// increments or decrements + /// - Otherwise, if start >= 0 && stop >= 0, + /// max(start, stop) iterator increments + /// - Otherwise, size() + max(start', stop') + /// iterator increments, where \c start' and \c stop' are the + /// offsets of the elements \c start and \c stop refer to. + /// + /// \note \c slice(start) should be implemented with a different + /// overload, rather than defaulting \c stop to + /// numeric_limits::max(), because + /// using a default would force non-random-access ranges to use an + /// O(size()) algorithm to compute the end rather + /// than the O(1) they're capable of. + range slice(difference_type start, difference_type stop) const { + static_assert( + std::is_convertible::value, + "Calling slice on a non-std::forward range would destroy the original " + "range."); + return dispatch_slice(start, stop, iterator_category()); + } + + range slice(difference_type start) const { + static_assert( + std::is_convertible::value, + "Calling slice on a non-std::forward range would destroy the original " + "range."); + return split(start).second; + } + + /// @} + +private: + // advance_upto: should be added to , but I'll use it as + // a helper function here. + // + // These return the number of increments that weren't applied + // because we ran into 'limit' (or 0 if we didn't run into limit). + static difference_type advance_upto(Iterator &it, difference_type n, + Iterator limit, std::input_iterator_tag) { + if (n < 0) + return 0; + while (it != limit && n > 0) { + ++it; + --n; + } + return n; + } + + static difference_type advance_upto(Iterator &it, difference_type n, + Iterator limit, + std::bidirectional_iterator_tag) { + if (n < 0) { + while (it != limit && n < 0) { + --it; + ++n; + } + } else { + while (it != limit && n > 0) { + ++it; + --n; + } + } + return n; + } + + static difference_type advance_upto(Iterator &it, difference_type n, + Iterator limit, + std::random_access_iterator_tag) { + difference_type distance = limit - it; + if (distance < 0) + assert(n <= 0); + else if (distance > 0) + assert(n >= 0); + + if (abs(distance) > abs(n)) { + it += n; + return 0; + } else { + it = limit; + return n - distance; + } + } + + // Dispatch functions. + difference_type dispatch_size(std::forward_iterator_tag) const { + return std::distance(begin(), end()); + } + + LLVM_CONSTEXPR difference_type dispatch_size( + std::random_access_iterator_tag) const { + return end() - begin(); + } + + std::pair dispatch_split_neg(difference_type index, + std::forward_iterator_tag) const { + assert(index < 0); + difference_type size = this->size(); + return split(std::max(0, size + index)); + } + + std::pair dispatch_split_neg( + difference_type index, std::bidirectional_iterator_tag) const { + assert(index < 0); + range first = *this; + first.pop_back_upto(-index); + return make_pair(first, range(first.end(), end())); + } + + range dispatch_slice(difference_type start, difference_type stop, + std::forward_iterator_tag) const { + if (start < 0 || stop < 0) { + difference_type size = this->size(); + if (start < 0) + start = std::max(0, size + start); + if (stop < 0) + stop = size + stop; // Possibly negative; will be fixed in 2 lines. + } + stop = std::max(start, stop); + + Iterator first = begin(); + advance_upto(first, start, end(), iterator_category()); + Iterator last = first; + advance_upto(last, stop - start, end(), iterator_category()); + return range(first, last); + } + + range dispatch_slice(const difference_type start, const difference_type stop, + std::bidirectional_iterator_tag) const { + Iterator first; + if (start < 0) { + first = end(); + advance_upto(first, start, begin(), iterator_category()); + } else { + first = begin(); + advance_upto(first, start, end(), iterator_category()); + } + Iterator last; + if (stop < 0) { + last = end(); + advance_upto(last, stop, first, iterator_category()); + } else { + if (start >= 0) { + last = first; + if (stop > start) + advance_upto(last, stop - start, end(), iterator_category()); + } else { + // Complicated: 'start' walked from the end of the sequence, + // but 'stop' needs to walk from the beginning. + Iterator dummy = begin(); + // Walk up to 'stop' increments from begin(), stopping when we + // get to 'first', and capturing the remaining number of + // increments. + difference_type increments_past_start = + advance_upto(dummy, stop, first, iterator_category()); + if (increments_past_start == 0) { + // If this is 0, then stop was before start. + last = first; + } else { + // Otherwise, count that many spaces beyond first. + last = first; + advance_upto(last, increments_past_start, end(), iterator_category()); + } + } + } + return range(first, last); + } + + range dispatch_slice(difference_type start, difference_type stop, + std::random_access_iterator_tag) const { + const difference_type size = this->size(); + if (start < 0) + start = size + start; + if (start < 0) + start = 0; + if (start > size) + start = size; + + if (stop < 0) + stop = size + stop; + if (stop < start) + stop = start; + if (stop > size) + stop = size; + + return range(begin() + start, begin() + stop); + } +}; + +/// \name deducing constructor wrappers +/// \relates std::range +/// \xmlonly \endxmlonly +/// +/// These functions do the same thing as the constructor with the same +/// signature. They just allow users to avoid writing the iterator +/// type. +/// @{ + +/// \todo I'd like to define a \c make_range taking a single iterator +/// argument representing the beginning of a range that ends with a +/// default-constructed \c Iterator. This would help with using +/// iterators like \c istream_iterator. However, using just \c +/// make_range() could be confusing and lead to people writing +/// incorrect ranges of more common iterators. Is there a better name? +template +LLVM_CONSTEXPR range make_range(Iterator begin, Iterator end) { + return range(begin, end); +} + +/// \par Participates in overload resolution if: +/// \c begin(r) and \c end(r) return the same type. +template LLVM_CONSTEXPR auto make_range( + Range &&r, + typename std::enable_if::value>::type* = 0) + -> range { + return range(r); +} + +/// \par Participates in overload resolution if: +/// - \c begin(r) and \c end(r) return the same type, +/// - that type satisfies the invariant that &*(i + N) == +/// (&*i) + N, and +/// - \c &*begin(r) has a pointer type. +template LLVM_CONSTEXPR auto make_ptr_range( + Range &&r, + typename std::enable_if< + detail::is_contiguous_range::value && + std::is_pointer::value>::type* = 0) + -> range { + return range(r); +} +/// @} +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Driver/CoreInputGraph.h b/external/bsd/llvm/dist/lld/include/lld/Driver/CoreInputGraph.h new file mode 100644 index 000000000..4a340a0f3 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Driver/CoreInputGraph.h @@ -0,0 +1,79 @@ +//===- lld/Driver/CoreInputGraph.h - Input Graph Node for Core linker -----===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Handles Options for CORE linking and provides InputElements +/// for the CORE linker +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_DRIVER_CORE_INPUT_GRAPH_H +#define LLD_DRIVER_CORE_INPUT_GRAPH_H + +#include "lld/Core/InputGraph.h" +#include "lld/ReaderWriter/CoreLinkingContext.h" + +#include + +namespace lld { + +/// \brief Represents a CORE File +class COREFileNode : public FileNode { +public: + COREFileNode(CoreLinkingContext &ctx, StringRef path) + : FileNode(path), _ctx(ctx) {} + + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::File; + } + + /// \brief validates the Input Element + virtual bool validate() { + (void)_ctx; + return true; + } + + /// \brief Parse the input file to lld::File. + error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) { + ErrorOr filePath = getPath(ctx); + if (!filePath && + error_code(filePath) == llvm::errc::no_such_file_or_directory) + return make_error_code(llvm::errc::no_such_file_or_directory); + + // Create a memory buffer + OwningPtr opmb; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(*filePath, opmb)) + return ec; + + std::unique_ptr mb(opmb.take()); + _buffer = std::move(mb); + return _ctx.getDefaultReader().parseFile(_buffer, _files); + } + + /// \brief Return the file that has to be processed by the resolver + /// to resolve atoms. This iterates over all the files thats part + /// of this node. Returns no_more_files when there are no files to be + /// processed + virtual ErrorOr getNextFile() { + if (_files.size() == _nextFileIndex) + return make_error_code(InputGraphError::no_more_files); + return *_files[_nextFileIndex++]; + } + + /// \brief Dump the Input Element + virtual bool dump(raw_ostream &) { return true; } + +private: + CoreLinkingContext &_ctx; +}; + +} // namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Driver/DarwinInputGraph.h b/external/bsd/llvm/dist/lld/include/lld/Driver/DarwinInputGraph.h new file mode 100644 index 000000000..14741aa50 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Driver/DarwinInputGraph.h @@ -0,0 +1,82 @@ +//===- lld/Driver/DarwinInputGraph.h - Input Graph Node for Mach-O linker -===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Handles Options for MachO linking and provides InputElements +/// for MachO linker +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_DRIVER_DARWIN_INPUT_GRAPH_H +#define LLD_DRIVER_DARWIN_INPUT_GRAPH_H + +#include "lld/Core/InputGraph.h" +#include "lld/ReaderWriter/MachOLinkingContext.h" + +#include + +namespace lld { + +/// \brief Represents a MachO File +class MachOFileNode : public FileNode { +public: + MachOFileNode(MachOLinkingContext &ctx, StringRef path, bool isWholeArchive) + : FileNode(path), _ctx(ctx), _isWholeArchive(isWholeArchive) {} + + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::File; + } + + /// \brief validates the Input Element + virtual bool validate() { + (void)_ctx; + return true; + } + + /// \brief Parse the input file to lld::File. + error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) { + ErrorOr filePath = getPath(ctx); + if (!filePath) + return error_code(filePath); + + if (error_code ec = getBuffer(*filePath)) + return ec; + + if (ctx.logInputFiles()) + diagnostics << *filePath << "\n"; + + if (filePath->endswith(".objtxt")) + return ctx.getYAMLReader().parseFile(_buffer, _files); + + (void) (_isWholeArchive); + return error_code::success(); + } + + /// \brief Return the file that has to be processed by the resolver + /// to resolve atoms. This iterates over all the files thats part + /// of this node. Returns no_more_files when there are no files to be + /// processed + virtual ErrorOr getNextFile() { + if (_files.size() == _nextFileIndex) + return make_error_code(InputGraphError::no_more_files); + return *_files[_nextFileIndex++]; + } + + /// \brief Dump the Input Element + virtual bool dump(raw_ostream &) { return true; } + +private: + const MachOLinkingContext &_ctx; + bool _isWholeArchive; +}; + +} // namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Driver/Driver.h b/external/bsd/llvm/dist/lld/include/lld/Driver/Driver.h new file mode 100644 index 000000000..bed585e32 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Driver/Driver.h @@ -0,0 +1,135 @@ +//===- lld/Driver/Driver.h - Linker Driver Emulator -----------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Interface for Drivers which convert command line arguments into +/// LinkingContext objects, then perform the link. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_DRIVER_DRIVER_H +#define LLD_DRIVER_DRIVER_H + +#include "lld/Core/InputGraph.h" +#include "lld/Core/LLVM.h" + +#include "llvm/ADT/Triple.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + +namespace lld { +class LinkingContext; +class CoreLinkingContext; +class MachOLinkingContext; +class PECOFFLinkingContext; +class ELFLinkingContext; + +/// Base class for all Drivers. +class Driver { +protected: + + /// Performs link using specified options + static bool link(LinkingContext &context, + raw_ostream &diagnostics = llvm::errs()); + +private: + Driver() LLVM_DELETED_FUNCTION; +}; + +/// Driver for "universal" lld tool which can mimic any linker command line +/// parsing once it figures out which command line flavor to use. +class UniversalDriver : public Driver { +public: + /// Determine flavor and pass control to Driver for that flavor. + static bool link(int argc, const char *argv[], + raw_ostream &diagnostics = llvm::errs()); + +private: + UniversalDriver() LLVM_DELETED_FUNCTION; +}; + +/// Driver for gnu/binutil 'ld' command line options. +class GnuLdDriver : public Driver { +public: + /// Parses command line arguments same as gnu/binutils ld and performs link. + /// Returns true iff an error occurred. + static bool linkELF(int argc, const char *argv[], + raw_ostream &diagnostics = llvm::errs()); + + /// Uses gnu/binutils style ld command line options to fill in options struct. + /// Returns true iff there was an error. + static bool parse(int argc, const char *argv[], + std::unique_ptr &context, + raw_ostream &diagnostics = llvm::errs()); + +private: + static llvm::Triple getDefaultTarget(const char *progName); + + GnuLdDriver() LLVM_DELETED_FUNCTION; +}; + +/// Driver for darwin/ld64 'ld' command line options. +class DarwinLdDriver : public Driver { +public: + /// Parses command line arguments same as darwin's ld and performs link. + /// Returns true iff there was an error. + static bool linkMachO(int argc, const char *argv[], + raw_ostream &diagnostics = llvm::errs()); + + /// Uses darwin style ld command line options to update LinkingContext object. + /// Returns true iff there was an error. + static bool parse(int argc, const char *argv[], MachOLinkingContext &info, + raw_ostream &diagnostics = llvm::errs()); + +private: + DarwinLdDriver() LLVM_DELETED_FUNCTION; +}; + +/// Driver for Windows 'link.exe' command line options +class WinLinkDriver : public Driver { +public: + /// Parses command line arguments same as Windows link.exe and performs link. + /// Returns true iff there was an error. + static bool linkPECOFF(int argc, const char *argv[], + raw_ostream &diagnostics = llvm::errs()); + + /// Uses Windows style link command line options to fill in options struct. + /// Returns true iff there was an error. + static bool parse(int argc, const char *argv[], PECOFFLinkingContext &info, + raw_ostream &diagnostics = llvm::errs(), + bool isDirective = false); + +private: + WinLinkDriver() LLVM_DELETED_FUNCTION; +}; + +/// Driver for lld unit tests +class CoreDriver : public Driver { +public: + + /// Parses command line arguments same as lld-core and performs link. + /// Returns true iff there was an error. + static bool link(int argc, const char *argv[], + raw_ostream &diagnostics = llvm::errs()); + + /// Uses lld-core command line options to fill in options struct. + /// Returns true iff there was an error. + static bool parse(int argc, const char *argv[], CoreLinkingContext &info, + raw_ostream &diagnostics = llvm::errs()); + +private: + CoreDriver() LLVM_DELETED_FUNCTION; +}; + +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Driver/GnuLdInputGraph.h b/external/bsd/llvm/dist/lld/include/lld/Driver/GnuLdInputGraph.h new file mode 100644 index 000000000..c7352b0d7 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Driver/GnuLdInputGraph.h @@ -0,0 +1,187 @@ +//===- lld/Driver/GnuLdInputGraph.h - Input Graph Node for ELF linker------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Handles Options for the GNU style linker for ELF and provides InputElements +/// for the GNU style linker for ELF +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_DRIVER_GNU_LD_INPUT_GRAPH_H +#define LLD_DRIVER_GNU_LD_INPUT_GRAPH_H + +#include "lld/Core/InputGraph.h" +#include "lld/Core/Resolver.h" +#include "lld/ReaderWriter/ELFLinkingContext.h" +#include "lld/ReaderWriter/FileArchive.h" + +namespace lld { + +/// \brief Represents a ELF File +class ELFFileNode : public FileNode { +public: + ELFFileNode(ELFLinkingContext &ctx, StringRef path, + std::vector searchPath, int64_t ordinal = -1, + bool isWholeArchive = false, bool asNeeded = false, + bool dashlPrefix = false) + : FileNode(path, ordinal), _elfLinkingContext(ctx), + _isWholeArchive(isWholeArchive), _asNeeded(asNeeded), + _isDashlPrefix(dashlPrefix) { + std::copy(searchPath.begin(), searchPath.end(), + std::back_inserter(_libraryPaths)); + } + + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::File; + } + + virtual ErrorOr getPath(const LinkingContext &ctx) const; + + /// \brief validates the Input Element + virtual bool validate() { return true; } + + /// \brief create an error string for printing purposes + virtual std::string errStr(error_code); + + /// \brief Dump the Input Element + virtual bool dump(raw_ostream &diagnostics) { + diagnostics << "Name : " << *getPath(_elfLinkingContext) << "\n"; + diagnostics << "Type : " + << "ELF File" + << "\n"; + diagnostics << "Ordinal : " << getOrdinal() << "\n"; + diagnostics << "Attributes : " + << "\n"; + diagnostics << " - wholeArchive : " + << ((_isWholeArchive) ? "true" : "false") << "\n"; + diagnostics << " - asNeeded : " << ((_asNeeded) ? "true" : "false") + << "\n"; + diagnostics << " contextPath : " << ((_libraryPaths.size()) ? "" : "None") + << "\n"; + for (auto path : _libraryPaths) + diagnostics << " - " << path << "\n"; + return true; + } + + /// \brief Parse the input file to lld::File. + error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) { + ErrorOr filePath = getPath(ctx); + if (!filePath) + return error_code(filePath); + + if (error_code ec = getBuffer(*filePath)) + return ec; + + if (ctx.logInputFiles()) + diagnostics << *filePath << "\n"; + + if (filePath->endswith(".objtxt")) + return ctx.getYAMLReader().parseFile(_buffer, _files); + + // Identify File type + llvm::sys::fs::file_magic FileType = + llvm::sys::fs::identify_magic(_buffer->getBuffer()); + + switch (FileType) { + case llvm::sys::fs::file_magic::elf_relocatable: + case llvm::sys::fs::file_magic::elf_shared_object: + // Call the default reader to read object files and shared objects + return _elfLinkingContext.getDefaultReader().parseFile(_buffer, _files); + + case llvm::sys::fs::file_magic::archive: { + // Process archive files. If Whole Archive option is set, + // parse all members of the archive. + error_code ec; + std::unique_ptr fileArchive( + new FileArchive(ctx, std::move(_buffer), ec, _isWholeArchive)); + if (_isWholeArchive) { + fileArchive->parseAllMembers(_files); + _archiveFile = std::move(fileArchive); + } else { + _files.push_back(std::move(fileArchive)); + } + return ec; + } + + default: + // Process Linker script + return _elfLinkingContext.getLinkerScriptReader().parseFile(_buffer, + _files); + } + } + + /// \brief This is used by Group Nodes, when there is a need to reset the + /// the file to be processed next. When handling a group node that contains + /// Input elements, if the group node has to be reprocessed, the linker needs + /// to start processing files as part of the inputelement from beginning. + /// reset the next file index to 0 only if the node is an archive library or + /// a shared library + virtual void resetNextIndex() { + if ((!_isWholeArchive && (_files[0]->kind() == File::kindArchiveLibrary)) || + (_files[0]->kind() == File::kindSharedLibrary)) + _nextFileIndex = 0; + setResolveState(Resolver::StateNoChange); + return; + } + + /// \brief Return the file that has to be processed by the resolver + /// to resolve atoms. This iterates over all the files thats part + /// of this node. Returns no_more_files when there are no files to be + /// processed + virtual ErrorOr getNextFile() { + if (_nextFileIndex == _files.size()) + return make_error_code(InputGraphError::no_more_files); + return *_files[_nextFileIndex++]; + } + +private: + llvm::BumpPtrAllocator _alloc; + const ELFLinkingContext &_elfLinkingContext; + bool _isWholeArchive; + bool _asNeeded; + bool _isDashlPrefix; + std::vector _libraryPaths; + std::unique_ptr _archiveFile; +}; + +/// \brief Represents a ELF control node +class ELFGroup : public Group { +public: + ELFGroup(ELFLinkingContext &ctx, int64_t ordinal) + : Group(ordinal), _elfLinkingContext(ctx) {} + + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::Control; + } + + /// \brief Validate the options + virtual bool validate() { + (void)_elfLinkingContext; + return true; + } + + /// \brief Dump the ELFGroup + virtual bool dump(raw_ostream &) { return true; } + + /// \brief Parse the group members. + error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) { + for (auto &ei : _elements) + if (error_code ec = ei->parse(ctx, diagnostics)) + return ec; + return error_code::success(); + } + +private: + const ELFLinkingContext &_elfLinkingContext; +}; + +} // namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Driver/WinLinkInputGraph.h b/external/bsd/llvm/dist/lld/include/lld/Driver/WinLinkInputGraph.h new file mode 100644 index 000000000..471bde7c2 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Driver/WinLinkInputGraph.h @@ -0,0 +1,101 @@ +//===- lld/Driver/WinLinkInputGraph.h - Input Graph Node for COFF linker --===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Handles Options for PECOFF linking and provides InputElements +/// for PECOFF linker +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_DRIVER_WIN_LINK_INPUT_GRAPH_H +#define LLD_DRIVER_WIN_LINK_INPUT_GRAPH_H + +#include "lld/Core/InputGraph.h" +#include "lld/ReaderWriter/PECOFFLinkingContext.h" +#include "lld/ReaderWriter/FileArchive.h" + +#include + +namespace lld { + +/// \brief Represents a PECOFF File +class PECOFFFileNode : public FileNode { +public: + PECOFFFileNode(PECOFFLinkingContext &ctx, StringRef path) + : FileNode(path), _ctx(ctx) {} + + static inline bool classof(const InputElement *a) { + return a->kind() == InputElement::Kind::File; + } + + virtual ErrorOr getPath(const LinkingContext &ctx) const; + + /// \brief Parse the input file to lld::File. + error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) { + ErrorOr filePath = getPath(ctx); + if (!filePath) + return error_code(filePath); + + if (error_code ec = getBuffer(*filePath)) + return ec; + + if (ctx.logInputFiles()) + diagnostics << *filePath << "\n"; + + if (filePath->endswith(".objtxt")) + return ctx.getYAMLReader().parseFile(_buffer, _files); + + llvm::sys::fs::file_magic FileType = + llvm::sys::fs::identify_magic(_buffer->getBuffer()); + std::unique_ptr f; + + switch (FileType) { + case llvm::sys::fs::file_magic::archive: { + // Archive File + error_code ec; + f.reset(new FileArchive(ctx, std::move(_buffer), ec, false)); + _files.push_back(std::move(f)); + return ec; + } + + case llvm::sys::fs::file_magic::coff_object: + default: + return _ctx.getDefaultReader().parseFile(_buffer, _files); + } + } + + /// \brief validates the Input Element + virtual bool validate() { return true; } + + /// \brief Dump the Input Element + virtual bool dump(raw_ostream &) { return true; } + + virtual ErrorOr getNextFile() { + if (_nextFileIndex == _files.size()) + return make_error_code(InputGraphError::no_more_files); + return *_files[_nextFileIndex++]; + } + +protected: + const PECOFFLinkingContext &_ctx; +}; + +/// \brief Represents a PECOFF Library File +class PECOFFLibraryNode : public PECOFFFileNode { +public: + PECOFFLibraryNode(PECOFFLinkingContext &ctx, StringRef path) + : PECOFFFileNode(ctx, path) {} + + virtual ErrorOr getPath(const LinkingContext &ctx) const; +}; + +} // namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/Passes/LayoutPass.h b/external/bsd/llvm/dist/lld/include/lld/Passes/LayoutPass.h new file mode 100644 index 000000000..bbd277f48 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Passes/LayoutPass.h @@ -0,0 +1,106 @@ +//===------ Passes/LayoutPass.h - Handles Layout of atoms ------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_PASSES_LAYOUT_PASS_H +#define LLD_PASSES_LAYOUT_PASS_H + +#include "lld/Core/Atom.h" +#include "lld/Core/File.h" +#include "lld/Core/Pass.h" +#include "lld/Core/range.h" +#include "lld/Core/Reference.h" + +#include "llvm/ADT/DenseMap.h" + +#include +#include +#include + +namespace lld { +class DefinedAtom; +class MutableFile; + +/// This linker pass does the layout of the atoms. The pass is done after the +/// order their .o files were found on the command line, then by order of the +/// atoms (address) in the .o file. But some atoms have a prefered location +/// in their section (such as pinned to the start or end of the section), so +/// the sort must take that into account too. +class LayoutPass : public Pass { +public: + + // Compare and Sort Atoms by their ordinals + class CompareAtoms { + public: + explicit CompareAtoms(const LayoutPass &pass) : _layout(pass) {} + bool operator()(const DefinedAtom *left, const DefinedAtom *right) const; + private: + bool compare(const DefinedAtom *left, const DefinedAtom *right, + std::string &reason) const; + const LayoutPass &_layout; + }; + + LayoutPass() : Pass(), _compareAtoms(*this) {} + + /// Sorts atoms in mergedFile by content type then by command line order. + virtual void perform(std::unique_ptr &mergedFile); + + virtual ~LayoutPass() {} + +private: + // Build the followOn atoms chain as specified by the kindLayoutAfter + // reference type + void buildFollowOnTable(MutableFile::DefinedAtomRange &range); + + // Build the followOn atoms chain as specified by the kindInGroup + // reference type + void buildInGroupTable(MutableFile::DefinedAtomRange &range); + + // Build the PrecededBy Table as specified by the kindLayoutBefore + // reference type + void buildPrecededByTable(MutableFile::DefinedAtomRange &range); + + // Build a map of Atoms to ordinals for sorting the atoms + void buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range); + + typedef llvm::DenseMap AtomToAtomT; + typedef llvm::DenseMap AtomToOrdinalT; + + // A map to be used to sort atoms. It represents the order of atoms in the + // result; if Atom X is mapped to atom Y in this map, X will be located + // immediately before Y in the output file. Y might be mapped to another + // atom, constructing a follow-on chain. An atom cannot be mapped to more + // than one atom unless all but one atom are of size zero. + AtomToAtomT _followOnNexts; + + // A map to be used to sort atoms. It's a map from an atom to its root of + // follow-on chain. A root atom is mapped to itself. If an atom is not in + // _followOnNexts, the atom is not in this map, and vice versa. + AtomToAtomT _followOnRoots; + + AtomToOrdinalT _ordinalOverrideMap; + CompareAtoms _compareAtoms; + + // Helper methods for buildFollowOnTable(). + const DefinedAtom *findAtomFollowedBy(const DefinedAtom *targetAtom); + bool checkAllPrevAtomsZeroSize(const DefinedAtom *targetAtom); + + void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root); + +#ifndef NDEBUG + // Check if the follow-on graph is a correct structure. For debugging only. + void checkFollowonChain(MutableFile::DefinedAtomRange &range); + + typedef std::vector::iterator DefinedAtomIter; + void checkTransitivity(DefinedAtomIter begin, DefinedAtomIter end) const; +#endif +}; + +} // namespace lld + +#endif // LLD_PASSES_LAYOUT_PASS_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripNativePass.h b/external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripNativePass.h new file mode 100644 index 000000000..0d562ed58 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripNativePass.h @@ -0,0 +1,41 @@ +//===--Passes/RoundTripNativePass.h - Write Native file/Read it back------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_PASSES_ROUND_TRIP_NATIVE_PASS_H +#define LLD_PASSES_ROUND_TRIP_NATIVE_PASS_H + +#include "lld/Core/File.h" +#include "lld/Core/LinkingContext.h" +#include "lld/Core/Pass.h" + +#include +#include + +namespace lld { +class RoundTripNativePass : public Pass { +public: + RoundTripNativePass(LinkingContext &context) : Pass(), _context(context) {} + + /// Writes to a native file and reads the atoms from the native file back. + /// Replaces mergedFile with the contents of the native File. + virtual void perform(std::unique_ptr &mergedFile); + + virtual ~RoundTripNativePass() {} + +private: + LinkingContext &_context; + // Keep the parsed file alive for the rest of the link. All atoms + // that are created by the RoundTripNativePass are owned by the + // nativeFile. + std::vector > _nativeFile; +}; + +} // namespace lld + +#endif // LLD_PASSES_ROUND_TRIP_NATIVE_PASS_H diff --git a/external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripYAMLPass.h b/external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripYAMLPass.h new file mode 100644 index 000000000..772bc7945 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/Passes/RoundTripYAMLPass.h @@ -0,0 +1,41 @@ +//===--Passes/RoundTripYAMLPass.h- Write YAML file/Read it back-----------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_PASSES_ROUND_TRIP_YAML_PASS_H +#define LLD_PASSES_ROUND_TRIP_YAML_PASS_H + +#include "lld/Core/File.h" +#include "lld/Core/LinkingContext.h" +#include "lld/Core/Pass.h" + +#include +#include + +namespace lld { +class RoundTripYAMLPass : public Pass { +public: + RoundTripYAMLPass(LinkingContext &context) : Pass(), _context(context) {} + + /// Writes to a YAML file and reads the atoms from the YAML file back. + /// Replaces the mergedFile with new contents. + virtual void perform(std::unique_ptr &mergedFile); + + virtual ~RoundTripYAMLPass() {} + +private: + LinkingContext &_context; + // Keep the parsed file alive for the rest of the link. All atoms + // that are created by the RoundTripYAMLPass are owned by the + // yamlFile. + std::vector > _yamlFile; +}; + +} // namespace lld + +#endif // LLD_PASSES_ROUND_TRIP_YAML_PASS_H diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/AtomLayout.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/AtomLayout.h new file mode 100644 index 000000000..e18246490 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/AtomLayout.h @@ -0,0 +1,41 @@ +//===- include/lld/ReaderWriter/AtomLayout.h ------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_ATOM_LAYOUT_H +#define LLD_READER_WRITER_ATOM_LAYOUT_H + +#include + +namespace lld { +class Atom; + +/// AtomLayouts are used by a writer to manage physical positions of atoms. +/// AtomLayout has two positions; one is file offset, and the other is the +/// address when loaded into memory. +/// +/// Construction of AtomLayouts is usually a multi-pass process. When an atom +/// is appended to a section, we don't know the starting address of the +/// section. Thus, we have no choice but to store the offset from the +/// beginning of the section as AtomLayout values. After all sections starting +/// address are fixed, AtomLayout is revisited to get the offsets updated by +/// adding the starting addresses of the section. +struct AtomLayout { + AtomLayout(const Atom *a, uint64_t fileOff, uint64_t virAddr) + : _atom(a), _fileOffset(fileOff), _virtualAddr(virAddr) {} + + AtomLayout() : _atom(nullptr), _fileOffset(0), _virtualAddr(0) {} + + const Atom *_atom; + uint64_t _fileOffset; + uint64_t _virtualAddr; +}; + +} + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/CoreLinkingContext.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/CoreLinkingContext.h new file mode 100644 index 000000000..3b74d3ab8 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/CoreLinkingContext.h @@ -0,0 +1,45 @@ +//===- lld/ReaderWriter/CoreLinkingContext.h ------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_CORE_LINKER_CONTEXT_H +#define LLD_READER_WRITER_CORE_LINKER_CONTEXT_H + +#include "lld/Core/LinkingContext.h" +#include "lld/ReaderWriter/Reader.h" +#include "lld/ReaderWriter/Writer.h" + +#include "llvm/Support/ErrorHandling.h" + +namespace lld { + +class CoreLinkingContext : public LinkingContext { +public: + CoreLinkingContext(); + + virtual bool validateImpl(raw_ostream &diagnostics); + virtual void addPasses(PassManager &pm); + virtual ErrorOr relocKindFromString(StringRef str) const; + virtual ErrorOr stringFromRelocKind(Reference::Kind kind) const; + + void addPassNamed(StringRef name) { _passNames.push_back(name); } + + virtual Reader &getDefaultReader() const { return *_reader; } + +protected: + virtual Writer &writer() const; + +private: + std::unique_ptr _reader; + std::unique_ptr _writer; + std::vector _passNames; +}; + +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ELFLinkingContext.h new file mode 100644 index 000000000..ed8b4aca7 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -0,0 +1,246 @@ +//===- lld/ReaderWriter/ELFLinkingContext.h -------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_ELF_LINKER_CONTEXT_H +#define LLD_READER_WRITER_ELF_LINKER_CONTEXT_H + +#include "lld/Core/LinkingContext.h" +#include "lld/Core/PassManager.h" +#include "lld/Core/Pass.h" +#include "lld/Core/range.h" + +#include "lld/ReaderWriter/Reader.h" +#include "lld/ReaderWriter/Writer.h" + +#include "llvm/ADT/Triple.h" +#include "llvm/Object/ELF.h" +#include "llvm/Support/ELF.h" + +#include + +namespace lld { +class DefinedAtom; +class Reference; + +namespace elf { +template class TargetHandler; +} + +class TargetHandlerBase { +public: + virtual ~TargetHandlerBase() {} +}; + +class ELFLinkingContext : public LinkingContext { +public: + + /// \brief The type of ELF executable that the linker + /// creates. + enum class OutputMagic : uint8_t { + DEFAULT, // The default mode, no specific magic set + NMAGIC, // Disallow shared libraries and dont align sections + // PageAlign Data, Mark Text Segment/Data segment RW + OMAGIC // Disallow shared libraries and dont align sections, + // Mark Text Segment/Data segment RW + }; + + llvm::Triple getTriple() const { return _triple; } + virtual bool is64Bits() const; + virtual bool isLittleEndian() const; + virtual uint64_t getPageSize() const { return 0x1000; } + OutputMagic getOutputMagic() const { return _outputMagic; } + uint16_t getOutputELFType() const { return _outputELFType; } + uint16_t getOutputMachine() const; + bool mergeCommonStrings() const { return _mergeCommonStrings; } + virtual uint64_t getBaseAddress() const { return _baseAddress; } + + /// This controls if undefined atoms need to be created for undefines that are + /// present in a SharedLibrary. If this option is set, undefined atoms are + /// created for every undefined symbol that are present in the dynamic table + /// in the shared library + bool useShlibUndefines() const { return _useShlibUndefines; } + /// @} + + /// \brief Does this relocation belong in the dynamic relocation table? + /// + /// This table is evaluated at loadtime by the dynamic loader and is + /// referenced by the DT_RELA{,ENT,SZ} entries in the dynamic table. + /// Relocations that return true will be added to the dynamic relocation + /// table. + virtual bool isDynamicRelocation(const DefinedAtom &, + const Reference &) const { + return false; + } + virtual bool validateImpl(raw_ostream &diagnostics); + + /// \brief Does the linker allow dynamic libraries to be linked with ? + /// This is true when the output mode of the executable is set to be + /// having NMAGIC/OMAGIC + virtual bool allowLinkWithDynamicLibraries() const { + if (_outputMagic == OutputMagic::NMAGIC || + _outputMagic == OutputMagic::OMAGIC || _noAllowDynamicLibraries) + return false; + return true; + } + + static std::unique_ptr create(llvm::Triple); + + /// \brief Does this relocation belong in the dynamic plt relocation table? + /// + /// This table holds all of the relocations used for delayed symbol binding. + /// It will be evaluated at load time if LD_BIND_NOW is set. It is referenced + /// by the DT_{JMPREL,PLTRELSZ} entries in the dynamic table. + /// Relocations that return true will be added to the dynamic plt relocation + /// table. + virtual bool isPLTRelocation(const DefinedAtom &, const Reference &) const { + return false; + } + + /// \brief The path to the dynamic interpreter + virtual StringRef getDefaultInterpreter() const { + return "/lib64/ld-linux-x86-64.so.2"; + } + + /// \brief The dynamic linker path set by the --dynamic-linker option + virtual StringRef getInterpreter() const { + if (_dynamicLinkerArg) + return _dynamicLinkerPath; + return getDefaultInterpreter(); + } + + virtual Reader &getDefaultReader() const { return *_elfReader; } + + virtual Reader &getLinkerScriptReader() const { return *_linkerScriptReader; } + + /// \brief Does the output have dynamic sections. + virtual bool isDynamic() const; + + /// \brief Is the relocation a relative relocation + virtual bool isRelativeReloc(const Reference &r) const; + + template + lld::elf::TargetHandler &getTargetHandler() const { + assert(_targetHandler && "Got null TargetHandler!"); + return static_cast &>(*_targetHandler.get()); + } + + virtual void addPasses(PassManager &pm); + + void setTriple(llvm::Triple trip) { _triple = trip; } + void setNoInhibitExec(bool v) { _noInhibitExec = v; } + void setIsStaticExecutable(bool v) { _isStaticExecutable = v; } + void setMergeCommonStrings(bool v) { _mergeCommonStrings = v; } + void setUseShlibUndefines(bool use) { _useShlibUndefines = use; } + + void setOutputELFType(uint32_t type) { _outputELFType = type; } + + /// \brief Set the dynamic linker path + void setInterpreter(StringRef dynamicLinker) { + _dynamicLinkerArg = true; + _dynamicLinkerPath = dynamicLinker; + } + + /// \brief Set NMAGIC output kind when the linker specifies --nmagic + /// or -n in the command line + /// Set OMAGIC output kind when the linker specifies --omagic + /// or -N in the command line + virtual void setOutputMagic(OutputMagic magic) { _outputMagic = magic; } + + /// \brief Disallow dynamic libraries during linking + virtual void setNoAllowDynamicLibraries() { _noAllowDynamicLibraries = true; } + + /// Searches directories for a match on the input File + ErrorOr + searchLibrary(StringRef libName, + const std::vector &searchPath) const; + + /// Get the entry symbol name + virtual StringRef entrySymbolName() const; + + /// add to the list of initializer functions + void addInitFunction(StringRef name) { _initFunctions.push_back(name); } + + /// add to the list of finalizer functions + void addFiniFunction(StringRef name) { _finiFunctions.push_back(name); } + + /// Return the list of initializer symbols that are specified in the + /// linker command line, using the -init option. + range initFunctions() const { + return _initFunctions; + } + + /// Return the list of finalizer symbols that are specified in the + /// linker command line, using the -fini option. + range finiFunctions() const { return _finiFunctions; } + + void setSharedObjectName(StringRef soname) { + _soname = soname; + } + + StringRef sharedObjectName() const { return _soname; } + + /// \brief Set path to the system root + void setSysroot(StringRef path) { + _sysrootPath = path; + } + + void addRpath(StringRef path) { + _rpathList.push_back(path); + } + + range getRpathList() const { + return _rpathList; + } + + void addRpathLink(StringRef path) { + _rpathLinkList.push_back(path); + } + + range getRpathLinkList() const { + return _rpathLinkList; + } + +private: + ELFLinkingContext() LLVM_DELETED_FUNCTION; + +protected: + ELFLinkingContext(llvm::Triple, std::unique_ptr); + + virtual Writer &writer() const; + + /// Method to create a internal file for an undefined symbol + virtual std::unique_ptr createUndefinedSymbolFile() const; + + uint16_t _outputELFType; // e.g ET_EXEC + llvm::Triple _triple; + std::unique_ptr _targetHandler; + uint64_t _baseAddress; + bool _isStaticExecutable; + bool _noInhibitExec; + bool _mergeCommonStrings; + bool _runLayoutPass; + bool _useShlibUndefines; + bool _dynamicLinkerArg; + bool _noAllowDynamicLibraries; + OutputMagic _outputMagic; + StringRefVector _inputSearchPaths; + std::unique_ptr _elfReader; + std::unique_ptr _writer; + std::unique_ptr _linkerScriptReader; + StringRef _dynamicLinkerPath; + StringRefVector _initFunctions; + StringRefVector _finiFunctions; + StringRef _sysrootPath; + StringRef _soname; + StringRefVector _rpathList; + StringRefVector _rpathLinkList; +}; +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/FileArchive.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/FileArchive.h new file mode 100644 index 000000000..9ef5021fc --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/FileArchive.h @@ -0,0 +1,176 @@ +//===- lld/ReaderWriter/FileArchive.h - Archive Library File -----------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +#ifndef LLD_READER_WRITER_FILE_ARCHIVE_H +#define LLD_READER_WRITER_FILE_ARCHIVE_H + +#include "lld/Core/ArchiveLibraryFile.h" + +#include "llvm/ADT/Hashing.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/Archive.h" +#include "llvm/Support/MemoryBuffer.h" + +#include + +namespace lld { + +/// \brief The FileArchive class represents an Archive Library file +class FileArchive : public ArchiveLibraryFile { +public: + + virtual ~FileArchive() { } + + /// \brief Check if any member of the archive contains an Atom with the + /// specified name and return the File object for that member, or nullptr. + virtual const File *find(StringRef name, bool dataSymbolOnly) const { + auto member = _symbolMemberMap.find(name); + if (member == _symbolMemberMap.end()) + return nullptr; + + llvm::object::Archive::child_iterator ci = member->second; + + if (dataSymbolOnly) { + OwningPtr buff; + if (ci->getMemoryBuffer(buff, true)) + return nullptr; + if (isDataSymbol(buff.take(), name)) + return nullptr; + } + + std::vector> result; + + OwningPtr buff; + if (ci->getMemoryBuffer(buff, true)) + return nullptr; + if (_context.logInputFiles()) + llvm::outs() << buff->getBufferIdentifier() << "\n"; + std::unique_ptr mb(buff.take()); + if (_context.getDefaultReader().parseFile(mb, result)) + return nullptr; + + assert(result.size() == 1); + + // give up the pointer so that this object no longer manages it + return result[0].release(); + } + + /// \brief Load all members of the archive ? + virtual bool isWholeArchive() const { return _isWholeArchive; } + + /// \brief parse each member + virtual error_code + parseAllMembers(std::vector> &result) const { + for (auto mf = _archive->begin_children(), + me = _archive->end_children(); mf != me; ++mf) { + OwningPtr buff; + error_code ec; + if ((ec = mf->getMemoryBuffer(buff, true))) + return ec; + if (_context.logInputFiles()) + llvm::outs() << buff->getBufferIdentifier() << "\n"; + std::unique_ptr mbc(buff.take()); + if ((ec = _context.getDefaultReader().parseFile(mbc, result))) + return ec; + } + return error_code::success(); + } + + virtual const atom_collection &defined() const { + return _definedAtoms; + } + + virtual const atom_collection &undefined() const { + return _undefinedAtoms; + } + + virtual const atom_collection &sharedLibrary() const { + return _sharedLibraryAtoms; + } + + virtual const atom_collection &absolute() const { + return _absoluteAtoms; + } + +protected: + error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const { + std::unique_ptr + obj(llvm::object::ObjectFile::createObjectFile(mb)); + error_code ec; + llvm::object::SymbolRef::Type symtype; + uint32_t symflags; + llvm::object::symbol_iterator ibegin = obj->begin_symbols(); + llvm::object::symbol_iterator iend = obj->end_symbols(); + StringRef symbolname; + + for (llvm::object::symbol_iterator i = ibegin; i != iend; i.increment(ec)) { + if (ec) return ec; + + // Get symbol name + if ((ec = (i->getName(symbolname)))) return ec; + + if (symbolname != symbol) + continue; + + // Get symbol flags + if ((ec = (i->getFlags(symflags)))) return ec; + + if (symflags <= llvm::object::SymbolRef::SF_Undefined) + continue; + + // Get Symbol Type + if ((ec = (i->getType(symtype)))) return ec; + + if (symtype == llvm::object::SymbolRef::ST_Data) { + return error_code::success(); + } + } + return llvm::object::object_error::parse_failed; + } + +private: + std::unique_ptr _archive; + atom_collection_vector _definedAtoms; + atom_collection_vector _undefinedAtoms; + atom_collection_vector _sharedLibraryAtoms; + atom_collection_vector _absoluteAtoms; + bool _isWholeArchive; + +public: + /// only subclasses of ArchiveLibraryFile can be instantiated + FileArchive(const LinkingContext &context, + std::unique_ptr mb, error_code &ec, + bool isWholeArchive) + : ArchiveLibraryFile(context, mb->getBufferIdentifier()), + _isWholeArchive(isWholeArchive) { + std::unique_ptr archive_obj( + new llvm::object::Archive(mb.release(), ec)); + if (ec) + return; + _archive.swap(archive_obj); + + // Cache symbols. + for (auto i = _archive->begin_symbols(), e = _archive->end_symbols(); + i != e; ++i) { + StringRef name; + llvm::object::Archive::child_iterator member; + if ((ec = i->getName(name))) + return; + if ((ec = i->getMember(member))) + return; + _symbolMemberMap[name] = member; + } + } + + std::unordered_map _symbolMemberMap; +}; // class FileArchive + +} // end namespace lld + +#endif // LLD_READER_WRITER_FILE_ARCHIVE_H diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/LinkerScript.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/LinkerScript.h new file mode 100644 index 000000000..7a46dc6b5 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/LinkerScript.h @@ -0,0 +1,228 @@ +//===- ReaderWriter/LinkerScript.h ----------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Linker script parser. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_LINKER_SCRIPT_H +#define LLD_READER_WRITER_LINKER_SCRIPT_H + +#include "lld/Core/LLVM.h" + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/system_error.h" + +namespace lld { +namespace script { +class Token { +public: + enum Kind { + unknown, + eof, + identifier, + l_paren, + r_paren, + kw_entry, + kw_group, + kw_output_format, + kw_as_needed + }; + + Token() : _kind(unknown) {} + Token(StringRef range, Kind kind) : _range(range), _kind(kind) {} + + void dump(raw_ostream &os) const; + + StringRef _range; + Kind _kind; +}; + +class Lexer { +public: + explicit Lexer(std::unique_ptr mb) + : _buffer(mb->getBuffer()) { + _sourceManager.AddNewSourceBuffer(mb.release(), llvm::SMLoc()); + } + + void lex(Token &tok); + + const llvm::SourceMgr &getSourceMgr() const { return _sourceManager; } + +private: + bool canStartName(char c) const; + bool canContinueName(char c) const; + void skipWhitespace(); + + Token _current; + /// \brief The current buffer state. + StringRef _buffer; + // Lexer owns the input files. + llvm::SourceMgr _sourceManager; +}; + +class Command { +public: + enum class Kind { + Entry, + OutputFormat, + Group, + }; + + Kind getKind() const { return _kind; } + + virtual void dump(raw_ostream &os) const = 0; + + virtual ~Command() {} + +protected: + explicit Command(Kind k) : _kind(k) {} + +private: + Kind _kind; +}; + +class OutputFormat : public Command { +public: + explicit OutputFormat(StringRef format) + : Command(Kind::OutputFormat), _format(format) {} + + static bool classof(const Command *c) { + return c->getKind() == Kind::OutputFormat; + } + + virtual void dump(raw_ostream &os) const { + os << "OUTPUT_FORMAT(" << getFormat() << ")\n"; + } + + StringRef getFormat() const { return _format; } + +private: + StringRef _format; +}; + +struct Path { + StringRef _path; + bool _asNeeded; + + Path() : _asNeeded(false) {} + explicit Path(StringRef path, bool asNeeded = false) + : _path(path), _asNeeded(asNeeded) {} +}; + +class Group : public Command { +public: + template + explicit Group(RangeT range) : Command(Kind::Group) { + using std::begin; + using std::end; + std::copy(begin(range), end(range), std::back_inserter(_paths)); + } + + static bool classof(const Command *c) { return c->getKind() == Kind::Group; } + + virtual void dump(raw_ostream &os) const { + os << "GROUP("; + bool first = true; + for (const auto &path : getPaths()) { + if (!first) + os << " "; + else + first = false; + if (path._asNeeded) + os << "AS_NEEDED("; + os << path._path; + if (path._asNeeded) + os << ")"; + } + os << ")\n"; + } + + const std::vector &getPaths() const { return _paths; } + +private: + std::vector _paths; +}; + +class Entry : public Command { +public: + explicit Entry(StringRef entryName) : + Command(Kind::Entry), _entryName(entryName) { } + + static bool classof(const Command *c) { + return c->getKind() == Kind::Entry; + } + + virtual void dump(raw_ostream &os) const { + os << "ENTRY(" << _entryName << ")\n"; + } + + const StringRef getEntryName() const { + return _entryName; + } + +private: + StringRef _entryName; +}; + +class LinkerScript { +public: + void dump(raw_ostream &os) const { + for (const auto &c : _commands) + c->dump(os); + } + + std::vector _commands; +}; + +class Parser { +public: + explicit Parser(Lexer &lex) : _lex(lex) {} + + LinkerScript *parse(); + +private: + void consumeToken() { _lex.lex(_tok); } + + void error(const Token &tok, Twine msg) { + _lex.getSourceMgr() + .PrintMessage(llvm::SMLoc::getFromPointer(tok._range.data()), + llvm::SourceMgr::DK_Error, msg); + } + + bool expectAndConsume(Token::Kind kind, Twine msg) { + if (_tok._kind != kind) { + error(_tok, msg); + return false; + } + consumeToken(); + return true; + } + + OutputFormat *parseOutputFormat(); + Group *parseGroup(); + bool parseAsNeeded(std::vector &paths); + Entry *parseEntry(); + +private: + llvm::BumpPtrAllocator _alloc; + LinkerScript _script; + Lexer &_lex; + Token _tok; +}; +} // end namespace script +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOFormat.hpp b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOFormat.hpp new file mode 100644 index 000000000..615be544b --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOFormat.hpp @@ -0,0 +1,627 @@ +//===- lib/ReaderWriter/MachO/MachOFormat.hpp -----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// +// This file contains all the structs and constants needed to write a +// mach-o final linked image. The names of the structs and constants +// are the same as in the darwin native header so +// they will be familiar to anyone who has used that header. +// + +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Memory.h" + +#ifndef LLD_READER_WRITER_MACHO_FORMAT_H +#define LLD_READER_WRITER_MACHO_FORMAT_H + +namespace lld { +namespace mach_o { + + +enum { + MH_MAGIC = 0xfeedface, + MH_MAGIC_64 = 0xfeedfacf +}; + +enum { + CPU_TYPE_ARM = 0x0000000C, + CPU_TYPE_I386 = 0x00000007, + CPU_TYPE_X86_64 = 0x01000007 +}; + +enum { + CPU_SUBTYPE_X86_ALL = 0x00000003, + CPU_SUBTYPE_X86_64_ALL = 0x00000003, + CPU_SUBTYPE_ARM_V6 = 0x00000006, + CPU_SUBTYPE_ARM_V7 = 0x00000009, + CPU_SUBTYPE_ARM_V7S = 0x0000000B +}; + +enum { + MH_OBJECT = 0x1, + MH_EXECUTE = 0x2, + MH_PRELOAD = 0x5, + MH_DYLIB = 0x6, + MH_DYLINKER = 0x7, + MH_BUNDLE = 0x8, + MH_DYLIB_STUB = 0x9, + MH_KEXT_BUNDLE= 0xB +}; + + +// +// Every mach-o file starts with this header. The header size is +// 28 bytes for 32-bit architecures and 32-bytes for 64-bit architectures. +// +class mach_header { +public: + uint32_t magic; + uint32_t cputype; + uint32_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; + uint32_t reserved; + + uint64_t size() { + return (magic == 0xfeedfacf) ? 32 : 28; + } + + void copyTo(uint8_t *to, bool swap=false) { + ::memcpy(to, (char*)&magic, this->size()); + } + + void recordLoadCommand(const class load_command *lc); +}; + + +// +// Every mach-o file has a list of load commands after the mach_header. +// Each load command starts with a type and length, so you can iterate +// through the load commands even if you don't understand the content +// of a particular type. +// +// The model for handling endianness and 32 vs 64 bitness is that the in-memory +// object is always 64-bit and the native endianess. The endianess swapping +// and pointer sizing is done when writing (copyTo method) or when reading +// (constructor that takes a buffer). +// +// The load_command subclasses are designed so to mirror the traditional "C" +// structs, so you can get and set the same field names (e.g. seg->vmaddr = 0). +// +class load_command { +public: + const uint32_t cmd; // type of load command + const uint32_t cmdsize; // length of load command including this header + + load_command(uint32_t cmdNumber, uint32_t sz, bool is64, bool align=false) + : cmd(cmdNumber), cmdsize(pointerAlign(sz, is64, align)) { + } + + virtual ~load_command() { + } + + virtual void copyTo(uint8_t *to, bool swap=false) = 0; +private: + // Load commands must be pointer-size aligned. Most load commands are + // a fixed size, so there is a runtime assert to check those. For variable + // length load commands, setting the align option to true will add padding + // at the end of the load command to round up its size for proper alignment. + uint32_t pointerAlign(uint32_t size, bool is64, bool align) { + if ( align ) { + if ( is64 ) + return (size + 7) & (-8); + else + return (size + 3) & (-4); + } + else { + if ( is64 ) + assert((size % 8) == 0); + else + assert((size % 4) == 0); + return size; + } + } + +}; + +inline void mach_header::recordLoadCommand(const load_command *lc) { + ++ncmds; + sizeofcmds += lc->cmdsize; +} + +// Supported load command types +enum { + LC_SEGMENT = 0x00000001, + LC_SYMTAB = 0x00000002, + LC_UNIXTHREAD = 0x00000005, + LC_LOAD_DYLIB = 0x0000000C, + LC_LOAD_DYLINKER = 0x0000000E, + LC_SEGMENT_64 = 0x00000019, + LC_MAIN = 0x80000028, + LC_DYLD_INFO_ONLY = 0x80000022 +}; + +// Memory protection bit used in segment_command.initprot +enum { + VM_PROT_NONE = 0x0, + VM_PROT_READ = 0x1, + VM_PROT_WRITE = 0x2, + VM_PROT_EXECUTE = 0x4, +}; + +// Bits for the section.flags field +enum { + // Section "type" is the low byte + SECTION_TYPE = 0x000000FF, + S_REGULAR = 0x00000000, + S_ZEROFILL = 0x00000001, + S_CSTRING_LITERALS = 0x00000002, + S_NON_LAZY_SYMBOL_POINTERS= 0x00000006, + S_LAZY_SYMBOL_POINTERS = 0x00000007, + S_SYMBOL_STUBS = 0x00000008, + + // Other bits in section.flags + S_ATTR_PURE_INSTRUCTIONS = 0x80000000, + S_ATTR_SOME_INSTRUCTIONS = 0x00000400 +}; + + +// section record for 32-bit architectures +struct section { + char sectname[16]; + char segname[16]; + uint32_t addr; + uint32_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; +}; + +// section record for 64-bit architectures +struct section_64 { + char sectname[16]; + char segname[16]; + uint64_t addr; + uint64_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; +}; + + +// +// A segment load command has a fixed set of fields followed by an 'nsect' +// array of section records. The in-memory object uses a pointer to +// a dynamically allocated array of sections. +// +class segment_command : public load_command { +public: + char segname[16]; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; + section_64 *sections; + + segment_command(unsigned sectCount, bool is64) + : load_command((is64 ? LC_SEGMENT_64 : LC_SEGMENT), + (is64 ? (72 + sectCount*80) : (56 + sectCount*68)), + is64), + vmaddr(0), vmsize(0), fileoff(0), filesize(0), + maxprot(0), initprot(0), nsects(sectCount), flags(0) { + sections = new section_64[sectCount]; + this->nsects = sectCount; + } + + ~segment_command() { + delete sections; + } + + void copyTo(uint8_t *to, bool swap) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + if( is64() ) { + // in-memory matches on-disk, so copy segment fields followed by sections + ::memcpy(to, (uint8_t*)&cmd, 72); + if ( nsects != 0 ) + ::memcpy(&to[72], sections, sizeof(section_64)*nsects); + } + else { + // on-disk is 32-bit struct, so copy each field + ::memcpy(to, (uint8_t*)&cmd, 24); + copy32(to, 24, vmaddr); + copy32(to, 28, vmsize); + copy32(to, 32, fileoff); + copy32(to, 36, filesize); + copy32(to, 40, maxprot); + copy32(to, 44, initprot); + copy32(to, 48, nsects); + copy32(to, 52, flags); + for(uint32_t i=0; i < nsects; ++i) { + unsigned off = 56+i*68; + ::memcpy(&to[off], sections[i].sectname, 32); + copy32(to, off+32, sections[i].addr); + copy32(to, off+36, sections[i].size); + copy32(to, off+40, sections[i].offset); + copy32(to, off+44, sections[i].align); + copy32(to, off+48, sections[i].reloff); + copy32(to, off+52, sections[i].nreloc); + copy32(to, off+56, sections[i].flags); + copy32(to, off+60, sections[i].reserved1); + copy32(to, off+64, sections[i].reserved2); + } + } + } + } + +private: + void copy32(uint8_t *to, unsigned offset, uint64_t value) { + uint32_t value32 = value; // FIXME: range check + ::memcpy(&to[offset], &value32, sizeof(uint32_t)); + } + + bool is64() { + return (cmd == LC_SEGMENT_64); + } +}; + + + +// +// The dylinker_command contains the path to the dynamic loader to use +// with the program (e.g. "/usr/lib/dyld"). So, it is variable length. +// But load commands must be pointer size aligned. +// +// +class dylinker_command : public load_command { +public: + uint32_t name_offset; +private: + StringRef _name; +public: + dylinker_command(StringRef path, bool is64) + : load_command(LC_LOAD_DYLINKER,12 + path.size(), is64, true), + name_offset(12), _name(path) { + } + + virtual void copyTo(uint8_t *to, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + // in-memory matches on-disk, so copy first fields followed by path + ::memcpy(to, (uint8_t*)&cmd, 12); + ::memcpy(&to[12], _name.data(), _name.size()); + ::memset(&to[12+_name.size()], 0, cmdsize-(12+_name.size())); + } + } + +}; + + + +// +// The symtab_command just holds the offset to the array of nlist structs +// and the offsets to the string pool for all symbol names. +// +class symtab_command : public load_command { +public: + uint32_t symoff; + uint32_t nsyms; + uint32_t stroff; + uint32_t strsize; + + symtab_command(bool is64) + : load_command(LC_SYMTAB, 24, is64), + symoff(0), nsyms(0), stroff(0), strsize(0) { + } + + virtual void copyTo(uint8_t *to, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + // in-memory matches on-disk, so copy fields + ::memcpy(to, (uint8_t*)&cmd, 24); + } + } + +}; + + +// +// The entry_point_command load command holds the offset to the function +// _main in a dynamic executable. +// +class entry_point_command : public load_command { +public: + uint64_t entryoff; + uint64_t stacksize; + + entry_point_command(bool is64) + : load_command(LC_MAIN, 24, is64), entryoff(0), stacksize(0) { + } + + virtual void copyTo(uint8_t *to, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + // in-memory matches on-disk, so copy fields + ::memcpy(to, (uint8_t*)&cmd, 24); + } + } +}; + + +// +// The thread_command load command holds the set of initial register values +// for a dynamic executable. In reality, only the PC and SP are used. +// +class thread_command : public load_command { +public: + uint32_t fields_flavor; + uint32_t fields_count; +private: + uint32_t _cpuType; + uint8_t *_registerArray; + +public: + thread_command(uint32_t cpuType, bool is64) + : load_command(LC_UNIXTHREAD, 16+registersBufferSize(cpuType), is64), + fields_count(registersBufferSize(cpuType)/4), _cpuType(cpuType) { + switch ( cpuType ) { + case CPU_TYPE_I386: + fields_flavor = 1; // i386_THREAD_STATE + break; + case CPU_TYPE_X86_64: + fields_flavor = 4; // x86_THREAD_STATE64; + break; + case CPU_TYPE_ARM: + fields_flavor = 1; // ARM_THREAD_STATE + break; + default: + assert(0 && "unsupported cpu type"); + } + _registerArray = reinterpret_cast( + ::calloc(registersBufferSize(cpuType), 1)); + assert(_registerArray); + } + + virtual void copyTo(uint8_t *to, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + // in-memory matches on-disk, so copy fixed fields + ::memcpy(to, (uint8_t*)&cmd, 16); + // that register array + ::memcpy(&to[16], _registerArray, registersBufferSize(_cpuType)); + } + } + + void setPC(uint64_t pc) { + uint32_t *regs32 = reinterpret_cast(_registerArray); + uint64_t *regs64 = reinterpret_cast(_registerArray); + switch ( _cpuType ) { + case CPU_TYPE_I386: + regs32[10] = pc; + break; + case CPU_TYPE_X86_64: + regs64[16] = pc; + break; + case CPU_TYPE_ARM: + regs32[15] = pc; + break; + default: + assert(0 && "unsupported cpu type"); + } + } + + virtual ~thread_command() { + ::free(_registerArray); + } + +private: + uint32_t registersBufferSize(uint32_t cpuType) { + switch ( cpuType ) { + case CPU_TYPE_I386: + return 64; // i386_THREAD_STATE_COUNT * 4 + case CPU_TYPE_X86_64: + return 168; // x86_THREAD_STATE64_COUNT * 4 + case CPU_TYPE_ARM: + return 68; // ARM_THREAD_STATE_COUNT * 4 + } + assert(0 && "unsupported cpu type"); + return 0; + } + + + +}; + + + + + +// +// The dylib_command load command holds the name/path of a dynamic shared +// library which this mach-o image depends on. +// +struct dylib_command : public load_command { + uint32_t name_offset; + uint32_t timestamp; + uint32_t current_version; + uint32_t compatibility_version; +private: + StringRef _loadPath; +public: + + dylib_command(StringRef path, bool is64) + : load_command(LC_LOAD_DYLIB, 24 + path.size(), is64, true), + name_offset(24), timestamp(0), + current_version(0x10000), compatibility_version(0x10000), + _loadPath(path) { + } + + virtual void copyTo(uint8_t *to, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + // in-memory matches on-disk, so copy first fields followed by path + ::memcpy(to, (uint8_t*)&cmd, 24); + ::memcpy(&to[24], _loadPath.data(), _loadPath.size()); + ::memset(&to[24+_loadPath.size()], 0, cmdsize-(24+_loadPath.size())); + } + } + +}; + + +// +// The dyld_info_command load command holds the offsets to various tables +// of information needed by dyld to prepare the image for execution. +// +struct dyld_info_command : public load_command { + uint32_t rebase_off; + uint32_t rebase_size; + uint32_t bind_off; + uint32_t bind_size; + uint32_t weak_bind_off; + uint32_t weak_bind_size; + uint32_t lazy_bind_off; + uint32_t lazy_bind_size; + uint32_t export_off; + uint32_t export_size; + + dyld_info_command(bool is64) + : load_command(LC_DYLD_INFO_ONLY, 48, is64), + rebase_off(0), rebase_size(0), + bind_off(0), bind_size(0), weak_bind_off(0), weak_bind_size(0), + lazy_bind_off(0), lazy_bind_size(0), export_off(0), export_size(0) { + } + + virtual void copyTo(uint8_t *to, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + // in-memory matches on-disk, so copy fields + ::memcpy(to, (uint8_t*)&cmd, 48); + } + } +}; + + +enum { + BIND_TYPE_POINTER = 1, + BIND_TYPE_TEXT_ABSOLUTE32 = 2, + BIND_TYPE_TEXT_PCREL32 = 3 +}; + +enum { + BIND_SPECIAL_DYLIB_SELF = 0, + BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1, + BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2 +}; + +enum { + BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1, + BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8 +}; + +enum { + BIND_OPCODE_MASK = 0xF0, + BIND_IMMEDIATE_MASK = 0x0F, + BIND_OPCODE_DONE = 0x00, + BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10, + BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20, + BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30, + BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40, + BIND_OPCODE_SET_TYPE_IMM = 0x50, + BIND_OPCODE_SET_ADDEND_SLEB = 0x60, + BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70, + BIND_OPCODE_ADD_ADDR_ULEB = 0x80, + BIND_OPCODE_DO_BIND = 0x90, + BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0, + BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0, + BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0 +}; + + + + +enum { + N_UNDF = 0x00, + N_EXT = 0x01, + N_PEXT = 0x10, + N_SECT = 0x0e +}; + +class nlist { +public: + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + uint16_t n_desc; + uint64_t n_value; + + static unsigned size(bool is64) { + return (is64 ? 16 : 12); + } + + void copyTo(uint8_t *to, bool is64, bool swap=false) { + if ( swap ) { + assert(0 && "non-native endianness not supported yet"); + } + else { + if ( is64 ) { + // in-memory matches on-disk, so just copy whole struct + ::memcpy(to, (uint8_t*)&n_strx, 16); + } + else { + // on-disk uses 32-bit n_value, so special case n_value + ::memcpy(to, (uint8_t*)&n_strx, 8); + uint32_t value32 = n_value; // FIXME: range check + ::memcpy(&to[8], &value32, sizeof(uint32_t)); + } + } + } +}; + + + + + +} // namespace mach_o +} // namespace lld + + + +#endif // LLD_READER_WRITER_MACHO_FORMAT_H + diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOLinkingContext.h new file mode 100644 index 000000000..a26ddc120 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/MachOLinkingContext.h @@ -0,0 +1,174 @@ +//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H +#define LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H + +#include "lld/Core/LinkingContext.h" +#include "lld/ReaderWriter/Reader.h" +#include "lld/ReaderWriter/Writer.h" + +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MachO.h" + +using llvm::MachO::HeaderFileType; + +namespace lld { + +namespace mach_o { +class KindHandler; // defined in lib. this header is in include. +} + +class MachOLinkingContext : public LinkingContext { +public: + MachOLinkingContext(); + ~MachOLinkingContext(); + + virtual void addPasses(PassManager &pm); + virtual ErrorOr relocKindFromString(StringRef str) const; + virtual ErrorOr stringFromRelocKind(Reference::Kind kind) const; + virtual bool validateImpl(raw_ostream &diagnostics); + + uint32_t getCPUType() const; + uint32_t getCPUSubType() const; + + bool addEntryPointLoadCommand() const; + bool addUnixThreadLoadCommand() const; + bool outputTypeHasEntry() const; + bool is64Bit() const; + + virtual uint64_t pageZeroSize() const { return _pageZeroSize; } + virtual uint64_t pageSize() const { return _pageSize; } + + mach_o::KindHandler &kindHandler() const; + + HeaderFileType outputFileType() const { return _outputFileType; } + + enum Arch { + arch_unknown, + arch_ppc, + arch_x86, + arch_x86_64, + arch_armv6, + arch_armv7, + arch_armv7s, + }; + + enum class OS { + unknown, macOSX, iOS, iOS_simulator + }; + + Arch arch() const { return _arch; } + OS os() const { return _os; } + + void setOutputFileType(HeaderFileType type) { _outputFileType = type; } + void setArch(Arch arch) { _arch = arch; } + bool setOS(OS os, StringRef minOSVersion); + bool minOS(StringRef mac, StringRef iOS) const; + void setDoNothing(bool value) { _doNothing = value; } + bool doNothing() const { return _doNothing; } + + virtual Reader &getDefaultReader() const { return *_machoReader; } + + /// \brief The dylib's binary compatibility version, in the raw uint32 format. + /// + /// When building a dynamic library, this is the compatibility version that + /// gets embedded into the result. Other Mach-O binaries that link against + /// this library will store the compatibility version in its load command. At + /// runtime, the loader will verify that the binary is compatible with the + /// installed dynamic library. + uint32_t compatibilityVersion() const { return _compatibilityVersion; } + + /// \brief The dylib's current version, in the the raw uint32 format. + /// + /// When building a dynamic library, this is the current version that gets + /// embedded into the result. Other Mach-O binaries that link against + /// this library will store the compatibility version in its load command. + uint32_t currentVersion() const { return _currentVersion; } + + /// \brief The dylib's install name. + /// + /// Binaries that link against the dylib will embed this path into the dylib + /// load command. When loading the binaries at runtime, this is the location + /// on disk that the loader will look for the dylib. + StringRef installName() const { return _installName; } + + /// \brief Whether or not the dylib has side effects during initialization. + /// + /// Dylibs marked as being dead strippable provide the guarantee that loading + /// the dylib has no side effects, allowing the linker to strip out the dylib + /// when linking a binary that does not use any of its symbols. + bool deadStrippableDylib() const { return _deadStrippableDylib; } + + /// \brief The path to the executable that will load the bundle at runtime. + /// + /// When building a Mach-O bundle, this executable will be examined if there + /// are undefined symbols after the main link phase. It is expected that this + /// binary will be loading the bundle at runtime and will provide the symbols + /// at that point. + StringRef bundleLoader() const { return _bundleLoader; } + + void setCompatibilityVersion(uint32_t vers) { _compatibilityVersion = vers; } + void setCurrentVersion(uint32_t vers) { _currentVersion = vers; } + void setInstallName(StringRef name) { _installName = name; } + void setDeadStrippableDylib(bool deadStrippable) { + _deadStrippableDylib = deadStrippable; + } + void setBundleLoader(StringRef loader) { _bundleLoader = loader; } + StringRef dyldPath() const { return "/usr/lib/dyld"; } + + static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype); + static Arch archFromName(StringRef archName); + static uint32_t cpuTypeFromArch(Arch arch); + static uint32_t cpuSubtypeFromArch(Arch arch); + static bool is64Bit(Arch arch); + static bool isHostEndian(Arch arch); + static bool isBigEndian(Arch arch); + + /// Construct 32-bit value from string "X.Y.Z" where + /// bits are xxxx.yy.zz. Largest number is 65535.255.255 + static bool parsePackedVersion(StringRef str, uint32_t &result); + +private: + virtual Writer &writer() const; + + struct ArchInfo { + StringRef archName; + MachOLinkingContext::Arch arch; + bool littleEndian; + uint32_t cputype; + uint32_t cpusubtype; + }; + + static ArchInfo _s_archInfos[]; + static const uint64_t unspecifiedPageZeroSize = UINT64_MAX; + + HeaderFileType _outputFileType; // e.g MH_EXECUTE + bool _outputFileTypeStatic; // Disambiguate static vs dynamic prog + bool _doNothing; // for -help and -v which just print info + Arch _arch; + OS _os; + uint32_t _osMinVersion; + uint64_t _pageZeroSize; + uint64_t _pageSize; + uint32_t _compatibilityVersion; + uint32_t _currentVersion; + StringRef _installName; + bool _deadStrippableDylib; + StringRef _bundleLoader; + mutable std::unique_ptr _kindHandler; + mutable std::unique_ptr _machoReader; + mutable std::unique_ptr _writer; + + +}; + +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h new file mode 100644 index 000000000..c5b681a8d --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h @@ -0,0 +1,338 @@ +//===- lld/ReaderWriter/PECOFFLinkingContext.h ----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_PECOFF_LINKING_CONTEXT_H +#define LLD_READER_WRITER_PECOFF_LINKING_CONTEXT_H + +#include +#include +#include + +#include "lld/Core/LinkingContext.h" +#include "lld/ReaderWriter/Reader.h" +#include "lld/ReaderWriter/Writer.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/COFF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileUtilities.h" + +using llvm::COFF::MachineTypes; +using llvm::COFF::WindowsSubsystem; + +static const uint8_t DEFAULT_DOS_STUB[128] = {'M', 'Z'}; + +namespace lld { + +class PECOFFLinkingContext : public LinkingContext { +public: + PECOFFLinkingContext() + : _baseAddress(0x400000), _stackReserve(1024 * 1024), _stackCommit(4096), + _heapReserve(1024 * 1024), _heapCommit(4096), _noDefaultLibAll(false), + _sectionDefaultAlignment(4096), + _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN), + _machineType(llvm::COFF::IMAGE_FILE_MACHINE_I386), _imageVersion(0, 0), + _minOSVersion(6, 0), _nxCompat(true), _largeAddressAware(false), + _allowBind(true), _allowIsolation(true), _swapRunFromCD(false), + _swapRunFromNet(false), _baseRelocationEnabled(true), + _terminalServerAware(true), _dynamicBaseEnabled(true), + _createManifest(true), _embedManifest(false), _manifestId(1), + _manifestLevel("'asInvoker'"), _manifestUiAccess("'false'"), + _imageType(ImageType::IMAGE_EXE), + _dosStub(llvm::makeArrayRef(DEFAULT_DOS_STUB)) { + setDeadStripping(true); + } + + struct Version { + Version(int v1, int v2) : majorVersion(v1), minorVersion(v2) {} + int majorVersion; + int minorVersion; + }; + + /// \brief Casting support + static inline bool classof(const LinkingContext *info) { return true; } + + enum ImageType { + IMAGE_EXE, + IMAGE_DLL + }; + + virtual Reader &getDefaultReader() const { return *_reader; } + + virtual Writer &writer() const; + virtual bool validateImpl(raw_ostream &diagnostics); + + virtual void addPasses(PassManager &pm); + + virtual bool + createImplicitFiles(std::vector > &result) const; + + void appendInputSearchPath(StringRef dirPath) { + _inputSearchPaths.push_back(dirPath); + } + + const std::vector getInputSearchPaths() { + return _inputSearchPaths; + } + + void registerTemporaryFile(StringRef path) { + std::unique_ptr fileRemover( + new llvm::FileRemover(Twine(allocateString(path)))); + _tempFiles.push_back(std::move(fileRemover)); + } + + StringRef searchLibraryFile(StringRef path) const; + + /// Returns the decorated name of the given symbol name. On 32-bit x86, it + /// adds "_" at the beginning of the string. On other architectures, the + /// return value is the same as the argument. + StringRef decorateSymbol(StringRef name) const { + if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) + return name; + std::string str = "_"; + str.append(name); + return allocateString(str); + } + + void setEntrySymbolName(StringRef name) { + if (!name.empty()) + LinkingContext::setEntrySymbolName(decorateSymbol(name)); + } + + void setBaseAddress(uint64_t addr) { _baseAddress = addr; } + uint64_t getBaseAddress() const { return _baseAddress; } + + void setStackReserve(uint64_t size) { _stackReserve = size; } + void setStackCommit(uint64_t size) { _stackCommit = size; } + uint64_t getStackReserve() const { return _stackReserve; } + uint64_t getStackCommit() const { return _stackCommit; } + + void setHeapReserve(uint64_t size) { _heapReserve = size; } + void setHeapCommit(uint64_t size) { _heapCommit = size; } + uint64_t getHeapReserve() const { return _heapReserve; } + uint64_t getHeapCommit() const { return _heapCommit; } + + void setSectionDefaultAlignment(uint32_t val) { + _sectionDefaultAlignment = val; + } + uint32_t getSectionDefaultAlignment() const { + return _sectionDefaultAlignment; + } + + void setSubsystem(WindowsSubsystem ss) { _subsystem = ss; } + WindowsSubsystem getSubsystem() const { return _subsystem; } + + void setMachineType(MachineTypes type) { _machineType = type; } + MachineTypes getMachineType() const { return _machineType; } + + void setImageVersion(const Version &version) { _imageVersion = version; } + Version getImageVersion() const { return _imageVersion; } + + void setMinOSVersion(const Version &version) { _minOSVersion = version; } + Version getMinOSVersion() const { return _minOSVersion; } + + void setNxCompat(bool nxCompat) { _nxCompat = nxCompat; } + bool isNxCompat() const { return _nxCompat; } + + void setLargeAddressAware(bool val) { _largeAddressAware = val; } + bool getLargeAddressAware() const { return _largeAddressAware; } + + void setAllowBind(bool val) { _allowBind = val; } + bool getAllowBind() const { return _allowBind; } + + void setAllowIsolation(bool val) { _allowIsolation = val; } + bool getAllowIsolation() const { return _allowIsolation; } + + void setSwapRunFromCD(bool val) { _swapRunFromCD = val; } + bool getSwapRunFromCD() const { return _swapRunFromCD; } + + void setSwapRunFromNet(bool val) { _swapRunFromNet = val; } + bool getSwapRunFromNet() const { return _swapRunFromNet; } + + void setBaseRelocationEnabled(bool val) { _baseRelocationEnabled = val; } + bool getBaseRelocationEnabled() const { return _baseRelocationEnabled; } + + void setTerminalServerAware(bool val) { _terminalServerAware = val; } + bool isTerminalServerAware() const { return _terminalServerAware; } + + void setDynamicBaseEnabled(bool val) { _dynamicBaseEnabled = val; } + bool getDynamicBaseEnabled() const { return _dynamicBaseEnabled; } + + void setCreateManifest(bool val) { _createManifest = val; } + bool getCreateManifest() const { return _createManifest; } + + void setManifestOutputPath(std::string val) { _manifestOutputPath = val; } + const std::string &getManifestOutputPath() const { + return _manifestOutputPath; + } + + void setEmbedManifest(bool val) { _embedManifest = val; } + bool getEmbedManifest() const { return _embedManifest; } + + void setManifestId(int val) { _manifestId = val; } + int getManifestId() const { return _manifestId; } + + void setManifestLevel(std::string val) { _manifestLevel = std::move(val); } + const std::string &getManifestLevel() const { return _manifestLevel; } + + void setManifestUiAccess(std::string val) { _manifestUiAccess = val; } + const std::string &getManifestUiAccess() const { return _manifestUiAccess; } + + void setManifestDependency(std::string val) { _manifestDependency = val; } + const std::string &getManifestDependency() const { + return _manifestDependency; + } + + void setImageType(ImageType type) { _imageType = type; } + ImageType getImageType() const { return _imageType; } + + StringRef getFinalSectionName(StringRef sectionName) const; + bool addSectionRenaming(raw_ostream &diagnostics, + StringRef from, StringRef to); + + void addNoDefaultLib(StringRef path) { _noDefaultLibs.insert(path); } + bool hasNoDefaultLib(StringRef path) const { + return _noDefaultLibs.count(path) == 1; + } + + void addDefaultLib(StringRef path) { _defaultLibs.insert(path); } + bool hasDefaultLib(StringRef path) const { + return _defaultLibs.count(path) == 1; + } + + void setNoDefaultLibAll(bool val) { _noDefaultLibAll = val; } + bool getNoDefaultLibAll() const { return _noDefaultLibAll; } + + virtual ErrorOr relocKindFromString(StringRef str) const; + virtual ErrorOr stringFromRelocKind(Reference::Kind kind) const; + + void setSectionAttributes(StringRef sectionName, uint32_t flags) { + _sectionAttributes[sectionName] = flags; + } + + llvm::Optional getSectionAttributes(StringRef sectionName) const { + auto it = _sectionAttributes.find(sectionName); + if (it == _sectionAttributes.end()) + return llvm::None; + return it->second; + } + + void setSectionAttributeMask(StringRef sectionName, uint32_t flags) { + _sectionAttributeMask[sectionName] = flags; + } + + uint32_t getSectionAttributeMask(StringRef sectionName) const { + auto it = _sectionAttributeMask.find(sectionName); + return it == _sectionAttributeMask.end() ? 0 : it->second; + } + + void setDosStub(ArrayRef data) { _dosStub = data; } + ArrayRef getDosStub() const { return _dosStub; } + + StringRef allocateString(StringRef ref) const { + char *x = _allocator.Allocate(ref.size() + 1); + memcpy(x, ref.data(), ref.size()); + x[ref.size()] = '\0'; + return x; + } + + ArrayRef allocate(ArrayRef array) const { + size_t size = array.size(); + uint8_t *p = _allocator.Allocate(size); + memcpy(p, array.data(), size); + return ArrayRef(p, p + array.size()); + } + + virtual bool hasInputGraph() { + if (_inputGraph) + return true; + return false; + } + +protected: + /// Method to create a internal file for the entry symbol + virtual std::unique_ptr createEntrySymbolFile() const; + + /// Method to create a internal file for an undefined symbol + virtual std::unique_ptr createUndefinedSymbolFile() const; + +private: + // The start address for the program. The default value for the executable is + // 0x400000, but can be altered using -base command line option. + uint64_t _baseAddress; + + uint64_t _stackReserve; + uint64_t _stackCommit; + uint64_t _heapReserve; + uint64_t _heapCommit; + bool _noDefaultLibAll; + uint32_t _sectionDefaultAlignment; + WindowsSubsystem _subsystem; + MachineTypes _machineType; + Version _imageVersion; + Version _minOSVersion; + bool _nxCompat; + bool _largeAddressAware; + bool _allowBind; + bool _allowIsolation; + bool _swapRunFromCD; + bool _swapRunFromNet; + bool _baseRelocationEnabled; + bool _terminalServerAware; + bool _dynamicBaseEnabled; + bool _createManifest; + std::string _manifestOutputPath; + bool _embedManifest; + int _manifestId; + std::string _manifestLevel; + std::string _manifestUiAccess; + std::string _manifestDependency; + ImageType _imageType; + + // The set to store /nodefaultlib arguments. + std::set _noDefaultLibs; + + // A set containing all the library files specified by /defaultlib. This is to + // keep track what files are already added to the input graph, in order to + // prevent adding the same file more than once to the input graph. + std::set _defaultLibs; + + std::vector _inputSearchPaths; + std::unique_ptr _reader; + std::unique_ptr _writer; + + // A map for section renaming. For example, if there is an entry in the map + // whose value is .rdata -> .text, the section contens of .rdata will be + // merged to .text in the resulting executable. + std::map _renamedSections; + + // Section attributes specified by /section option. The uint32_t value will be + // copied to the Characteristics field of the section header. + std::map _sectionAttributes; + + // Section attributes specified by /section option in conjunction with the + // negative flag "!". The uint32_t value is a mask of section attributes that + // should be disabled. + std::map _sectionAttributeMask; + + // List of files that will be removed on destruction. + std::vector > _tempFiles; + + // DOS Stub. DOS stub is data located at the beginning of PE/COFF file. + // Windows loader do not really care about DOS stub contents, but it's usually + // a small DOS program that prints out a message "This program requires + // Microsoft Windows." This feature was somewhat useful before Windows 95. + ArrayRef _dosStub; +}; + +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Reader.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Reader.h new file mode 100644 index 000000000..436e45e15 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Reader.h @@ -0,0 +1,56 @@ +//===- lld/ReaderWriter/Reader.h - Abstract File Format Reading Interface -===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_READER_H +#define LLD_READER_WRITER_READER_H + +#include "lld/Core/LLVM.h" + +#include +#include +#include + +namespace lld { +class ELFLinkingContext; +class File; +class LinkingContext; +class PECOFFLinkingContext; + +/// \brief An abstract class for reading object files, library files, and +/// executable files. +/// +/// Each file format (e.g. ELF, mach-o, PECOFF, native, etc) have a concrete +/// subclass of Reader. +class Reader { +public: + virtual ~Reader(); + + /// \brief Parse a supplied buffer (already filled with the contents of a + /// file) and create a File object. + /// + /// On success, the resulting File object takes ownership of the MemoryBuffer. + virtual error_code + parseFile(std::unique_ptr &mb, + std::vector > &result) const = 0; + +protected: + // only concrete subclasses can be instantiated + Reader(const LinkingContext &context) : _context(context) {} + + const LinkingContext &_context; +}; + +std::unique_ptr createReaderELF(const ELFLinkingContext &); +std::unique_ptr createReaderMachO(const LinkingContext &); +std::unique_ptr createReaderNative(const LinkingContext &); +std::unique_ptr createReaderPECOFF(PECOFFLinkingContext &); +std::unique_ptr createReaderYAML(const LinkingContext &); +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ReaderLinkerScript.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ReaderLinkerScript.h new file mode 100644 index 000000000..0a1e3def3 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/ReaderLinkerScript.h @@ -0,0 +1,34 @@ +//===- lld/ReaderWriter/ReaderLinkerScript.h ------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_READER_LINKER_SCRIPT_H +#define LLD_READER_WRITER_READER_LINKER_SCRIPT_H + +#include "lld/Core/LLVM.h" +#include "lld/ReaderWriter/Reader.h" + +namespace lld { +class File; +class LinkingContext; + +/// \brief ReaderLinkerScript is a class for reading linker scripts +class ReaderLinkerScript : public Reader { +public: + explicit ReaderLinkerScript(const LinkingContext &context) + : Reader(context) {} + + /// \brief Returns a vector of Files that are contained in the archive file + /// pointed to by the Memorybuffer + error_code parseFile(std::unique_ptr &mb, + std::vector > &result) const; +}; + +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/RelocationHelperFunctions.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/RelocationHelperFunctions.h new file mode 100644 index 000000000..427f66120 --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/RelocationHelperFunctions.h @@ -0,0 +1,53 @@ +//===- lld/ReaderWriter/RelocationHelperFunctions.h------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_RELOCATION_HELPER_FUNCTIONS_H +#define LLD_READER_WRITER_RELOCATION_HELPER_FUNCTIONS_H + +namespace lld { + +/// \brief Return the bits that are described by the mask +template < typename T > +T gatherBits(T val, T mask) +{ + T result = 0; + size_t off = 0; + + for (size_t bit = 0; bit != sizeof (T) * 8; ++bit) { + const bool valBit = (val >> bit) & 1; + const bool maskBit = (mask >> bit) & 1; + if (maskBit) { + result |= static_cast (valBit) << off; + ++off; + } + } + return result; +} + +/// \brief Set the bits as described by the mask +template +T scatterBits(T val, T mask) +{ + T result = 0; + size_t off = 0; + + for (size_t bit = 0; bit != sizeof (T) * 8; ++bit) { + const bool valBit = (val >> off) & 1; + const bool maskBit = (mask >> bit) & 1; + if (maskBit) { + result |= static_cast(valBit) << bit; + ++off; + } + } + return result; +} + +} // namespace lld + +#endif // LLD_READER_WRITER_RELOCATION_HELPER_FUNCTIONS_H diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Simple.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Simple.h new file mode 100644 index 000000000..dcae7f15c --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Simple.h @@ -0,0 +1,204 @@ +//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Provide simple implementations for Atoms and File. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_SIMPLE_H +#define LLD_READER_WRITER_SIMPLE_H + +#include "lld/Core/DefinedAtom.h" +#include "lld/Core/File.h" +#include "lld/Core/Reference.h" +#include "lld/Core/UndefinedAtom.h" + +namespace lld { +class SimpleFile : public MutableFile { +public: + SimpleFile(const LinkingContext &context, StringRef path) + : MutableFile(context, path) {} + + virtual void addAtom(const Atom &atom) { + if (const DefinedAtom *defAtom = dyn_cast(&atom)) { + _definedAtoms._atoms.push_back(defAtom); + } else if ( + const UndefinedAtom *undefAtom = dyn_cast(&atom)) { + _undefinedAtoms._atoms.push_back(undefAtom); + } else if ( + const SharedLibraryAtom *slAtom = dyn_cast(&atom)) { + _sharedLibraryAtoms._atoms.push_back(slAtom); + } else if (const AbsoluteAtom *abAtom = dyn_cast(&atom)) { + _absoluteAtoms._atoms.push_back(abAtom); + } else { + llvm_unreachable("atom has unknown definition kind"); + } + } + + virtual const atom_collection &defined() const { + return _definedAtoms; + } + + virtual const atom_collection &undefined() const { + return _undefinedAtoms; + } + + virtual const atom_collection &sharedLibrary() const { + return _sharedLibraryAtoms; + } + + virtual const atom_collection &absolute() const { + return _absoluteAtoms; + } + + virtual DefinedAtomRange definedAtoms() { + return make_range(_definedAtoms._atoms); + } + +protected: + atom_collection_vector _definedAtoms; + atom_collection_vector _undefinedAtoms; + atom_collection_vector _sharedLibraryAtoms; + atom_collection_vector _absoluteAtoms; +}; + +class FileToMutable : public SimpleFile { +public: + FileToMutable(const LinkingContext &context, File &file) + : SimpleFile(context, file.path()) { + for (auto definedAtom : file.defined()) + _definedAtoms._atoms.push_back(std::move(definedAtom)); + for (auto undefAtom : file.undefined()) + _undefinedAtoms._atoms.push_back(std::move(undefAtom)); + for (auto shlibAtom : file.sharedLibrary()) + _sharedLibraryAtoms._atoms.push_back(std::move(shlibAtom)); + for (auto absAtom : file.absolute()) + _absoluteAtoms._atoms.push_back(std::move(absAtom)); + } +}; + +class SimpleReference : public Reference { +public: + SimpleReference(Reference::Kind k, uint64_t off, const Atom *t, + Reference::Addend a) + : _target(t), _offsetInAtom(off), _addend(a) { + _kind = k; + } + + virtual uint64_t offsetInAtom() const { return _offsetInAtom; } + + virtual const Atom *target() const { return _target; } + + virtual Addend addend() const { return _addend; } + + virtual void setAddend(Addend a) { _addend = a; } + + virtual void setTarget(const Atom *newAtom) { _target = newAtom; } +private: + const Atom *_target; + uint64_t _offsetInAtom; + Addend _addend; +}; + +class SimpleDefinedAtom : public DefinedAtom { +public: + explicit SimpleDefinedAtom(const File &f) : _file(f) { + static uint32_t lastOrdinal = 0; + _ordinal = lastOrdinal++; + } + + virtual const File &file() const { return _file; } + + virtual StringRef name() const { return StringRef(); } + + virtual uint64_t ordinal() const { return _ordinal; } + + virtual Scope scope() const { return DefinedAtom::scopeLinkageUnit; } + + virtual Interposable interposable() const { return DefinedAtom::interposeNo; } + + virtual Merge merge() const { return DefinedAtom::mergeNo; } + + virtual Alignment alignment() const { return Alignment(0, 0); } + + virtual SectionChoice sectionChoice() const { + return DefinedAtom::sectionBasedOnContent; + } + + virtual SectionPosition sectionPosition() const { + return DefinedAtom::sectionPositionAny; + } + + virtual StringRef customSectionName() const { return StringRef(); } + virtual DeadStripKind deadStrip() const { + return DefinedAtom::deadStripNormal; + } + + virtual bool isAlias() const { return false; } + + virtual DefinedAtom::reference_iterator begin() const { + uintptr_t index = 0; + const void *it = reinterpret_cast(index); + return reference_iterator(*this, it); + } + + virtual DefinedAtom::reference_iterator end() const { + uintptr_t index = _references.size(); + const void *it = reinterpret_cast(index); + return reference_iterator(*this, it); + } + + virtual const Reference *derefIterator(const void *it) const { + uintptr_t index = reinterpret_cast(it); + assert(index < _references.size()); + return &_references[index]; + } + + virtual void incrementIterator(const void *&it) const { + uintptr_t index = reinterpret_cast(it); + ++index; + it = reinterpret_cast(index); + } + + void addReference(Reference::Kind kind, uint64_t offset, const Atom *target, + Reference::Addend addend) { + _references.push_back(SimpleReference(kind, offset, target, addend)); + } + + void setOrdinal(uint64_t ord) { _ordinal = ord; } + +private: + const File &_file; + uint64_t _ordinal; + std::vector _references; +}; + +class SimpleUndefinedAtom : public UndefinedAtom { +public: + SimpleUndefinedAtom(const File &f, StringRef name) : _file(f), _name(name) { + assert(!name.empty() && "UndefinedAtoms must have a name"); + } + + /// file - returns the File that produced/owns this Atom + virtual const File &file() const { return _file; } + + /// name - The name of the atom. For a function atom, it is the (mangled) + /// name of the function. + virtual StringRef name() const { return _name; } + + virtual CanBeNull canBeNull() const { return UndefinedAtom::canBeNullNever; } + +private: + const File &_file; + StringRef _name; +}; +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Writer.h b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Writer.h new file mode 100644 index 000000000..2f33bb38a --- /dev/null +++ b/external/bsd/llvm/dist/lld/include/lld/ReaderWriter/Writer.h @@ -0,0 +1,52 @@ +//===- lld/ReaderWriter/Writer.h - Abstract File Format Interface ---------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_WRITER_H +#define LLD_READER_WRITER_WRITER_H + +#include "lld/Core/LLVM.h" + +#include +#include + +namespace lld { +class ELFLinkingContext; +class File; +class MachOLinkingContext; +class PECOFFLinkingContext; +class LinkingContext; + +/// \brief The Writer is an abstract class for writing object files, shared +/// library files, and executable files. Each file format (e.g. ELF, mach-o, +/// PECOFF, native, etc) have a concrete subclass of Writer. +class Writer { +public: + virtual ~Writer(); + + /// \brief Write a file from the supplied File object + virtual error_code writeFile(const File &linkedFile, StringRef path) = 0; + + /// \brief This method is called by Core Linking to give the Writer a chance + /// to add file format specific "files" to set of files to be linked. This is + /// how file format specific atoms can be added to the link. + virtual bool createImplicitFiles(std::vector > &); + +protected: + // only concrete subclasses can be instantiated + Writer(); +}; + +std::unique_ptr createWriterELF(const ELFLinkingContext &); +std::unique_ptr createWriterMachO(const MachOLinkingContext &); +std::unique_ptr createWriterNative(const LinkingContext &); +std::unique_ptr createWriterPECOFF(const PECOFFLinkingContext &); +std::unique_ptr createWriterYAML(const LinkingContext &); +} // end namespace lld + +#endif diff --git a/external/bsd/llvm/dist/lld/lib/CMakeLists.txt b/external/bsd/llvm/dist/lld/lib/CMakeLists.txt new file mode 100644 index 000000000..3a714e7b3 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(Core) +add_subdirectory(Driver) +add_subdirectory(Passes) +add_subdirectory(ReaderWriter) diff --git a/external/bsd/llvm/dist/lld/lib/Core/CMakeLists.txt b/external/bsd/llvm/dist/lld/lib/Core/CMakeLists.txt new file mode 100644 index 000000000..1df4f0167 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/CMakeLists.txt @@ -0,0 +1,17 @@ +set(LLVM_LINK_COMPONENTS support) + +add_lld_library(lldCore + DefinedAtom.cpp + Error.cpp + File.cpp + InputGraph.cpp + LinkingContext.cpp + PassManager.cpp + Resolver.cpp + SymbolTable.cpp + ) + +target_link_libraries(lldCore + lldNative + lldYAML + ) diff --git a/external/bsd/llvm/dist/lld/lib/Core/DefinedAtom.cpp b/external/bsd/llvm/dist/lld/lib/Core/DefinedAtom.cpp new file mode 100644 index 000000000..239e6ba88 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/DefinedAtom.cpp @@ -0,0 +1,84 @@ +//===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ErrorHandling.h" + +#include "lld/Core/DefinedAtom.h" + + +namespace lld { + + +DefinedAtom::ContentPermissions DefinedAtom::permissions() const { + // By default base permissions on content type. + return permissions(this->contentType()); +} + +// Utility function for deriving permissions from content type +DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) { + switch (type) { + case typeCode: + case typeResolver: + case typeBranchIsland: + case typeBranchShim: + case typeStub: + case typeStubHelper: + return permR_X; + + case typeConstant: + case typeCString: + case typeUTF16String: + case typeCFI: + case typeLSDA: + case typeLiteral4: + case typeLiteral8: + case typeLiteral16: + case typeDTraceDOF: + case typeCompactUnwindInfo: + case typeRONote: + case typeNoAlloc: + return permR__; + + case typeData: + case typeDataFast: + case typeZeroFill: + case typeZeroFillFast: + case typeObjC1Class: + case typeLazyPointer: + case typeLazyDylibPointer: + case typeThunkTLV: + case typeDataDirectoryEntry: + case typeRWNote: + return permRW_; + + case typeGOT: + case typeConstData: + case typeCFString: + case typeInitializerPtr: + case typeTerminatorPtr: + case typeCStringPtr: + case typeObjCClassPtr: + case typeObjC2CategoryList: + case typeTLVInitialData: + case typeTLVInitialZeroFill: + case typeTLVInitializerPtr: + case typeThreadData: + case typeThreadZeroFill: + return permRW_L; + + case typeUnknown: + case typeTempLTO: + return permUnknown; + } + llvm_unreachable("unknown content type"); +} + + +} // namespace + diff --git a/external/bsd/llvm/dist/lld/lib/Core/Error.cpp b/external/bsd/llvm/dist/lld/lib/Core/Error.cpp new file mode 100644 index 000000000..34c785dc7 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/Error.cpp @@ -0,0 +1,129 @@ +//===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/Error.h" + +#include "llvm/Support/ErrorHandling.h" + +using namespace lld; + +class _NativeReaderErrorCategory : public llvm::_do_message { +public: + virtual const char* name() const { + return "lld.native.reader"; + } + + virtual std::string message(int ev) const { + if (NativeReaderError(ev) == NativeReaderError::success) + return "Success"; + if (NativeReaderError(ev) == NativeReaderError::unknown_file_format) + return "Unknown file format"; + if (NativeReaderError(ev) == NativeReaderError::file_too_short) + return "file truncated"; + if (NativeReaderError(ev) == NativeReaderError::file_malformed) + return "file malformed"; + if (NativeReaderError(ev) == NativeReaderError::memory_error) + return "out of memory"; + if (NativeReaderError(ev) == NativeReaderError::unknown_chunk_type) + return "unknown chunk type"; + llvm_unreachable("An enumerator of NativeReaderError does not have a " + "message defined."); + } + + virtual llvm::error_condition default_error_condition(int ev) const { + if (NativeReaderError(ev) == NativeReaderError::success) + return llvm::errc::success; + return llvm::errc::invalid_argument; + } +}; + +const llvm::error_category &lld::native_reader_category() { + static _NativeReaderErrorCategory o; + return o; +} + +class _YamlReaderErrorCategory : public llvm::_do_message { +public: + virtual const char* name() const { + return "lld.yaml.reader"; + } + + virtual std::string message(int ev) const { + if (YamlReaderError(ev) == YamlReaderError::success) + return "Success"; + if (YamlReaderError(ev) == YamlReaderError::unknown_keyword) + return "Unknown keyword found in yaml file"; + if (YamlReaderError(ev) == YamlReaderError::illegal_value) + return "Bad value found in yaml file"; + llvm_unreachable("An enumerator of YamlReaderError does not have a " + "message defined."); + } + + virtual llvm::error_condition default_error_condition(int ev) const { + if (YamlReaderError(ev) == YamlReaderError::success) + return llvm::errc::success; + return llvm::errc::invalid_argument; + } +}; + +const llvm::error_category &lld::YamlReaderCategory() { + static _YamlReaderErrorCategory o; + return o; +} + +class _LinkerScriptReaderErrorCategory : public llvm::_do_message { +public: + virtual const char *name() const { return "lld.linker-script.reader"; } + + virtual std::string message(int ev) const { + LinkerScriptReaderError e = LinkerScriptReaderError(ev); + if (e == LinkerScriptReaderError::success) + return "Success"; + if (e == LinkerScriptReaderError::parse_error) + return "Error parsing linker script"; + llvm_unreachable( + "An enumerator of LinkerScriptReaderError does not have a " + "message defined."); + } + + virtual llvm::error_condition default_error_condition(int ev) const { + LinkerScriptReaderError e = LinkerScriptReaderError(ev); + if (e == LinkerScriptReaderError::success) + return llvm::errc::success; + return llvm::errc::invalid_argument; + } +}; + +const llvm::error_category &lld::LinkerScriptReaderCategory() { + static _LinkerScriptReaderErrorCategory o; + return o; +} + +class _InputGraphErrorCategory : public llvm::_do_message { +public: + virtual const char *name() const { return "lld.inputGraph.parse"; } + + virtual std::string message(int ev) const { + if (InputGraphError(ev) == InputGraphError::success) + return "Success"; + llvm_unreachable("An enumerator of InputGraphError does not have a " + "message defined."); + } + + virtual llvm::error_condition default_error_condition(int ev) const { + if (InputGraphError(ev) == InputGraphError::success) + return llvm::errc::success; + return llvm::errc::invalid_argument; + } +}; + +const llvm::error_category &lld::InputGraphErrorCategory() { + static _InputGraphErrorCategory i; + return i; +} diff --git a/external/bsd/llvm/dist/lld/lib/Core/File.cpp b/external/bsd/llvm/dist/lld/lib/Core/File.cpp new file mode 100644 index 000000000..bc3228f7f --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/File.cpp @@ -0,0 +1,30 @@ +//===- Core/File.cpp - A Container of Atoms -------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/File.h" +#include "lld/Core/LLVM.h" + +namespace lld { + +File::~File() {} + +StringRef File::translationUnitSource() const { + return StringRef(); +} + + +File::atom_collection_empty File::_noDefinedAtoms; +File::atom_collection_empty File::_noUndefinedAtoms; +File::atom_collection_empty File::_noSharedLibraryAtoms; +File::atom_collection_empty File::_noAbsoluteAtoms; + + + + +} // namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Core/InputGraph.cpp b/external/bsd/llvm/dist/lld/lib/Core/InputGraph.cpp new file mode 100644 index 000000000..920c7bddc --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/InputGraph.cpp @@ -0,0 +1,178 @@ +//===- lib/Core/InputGraph.cpp --------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/InputGraph.h" + +#include "lld/Core/Resolver.h" + +using namespace lld; + +namespace { +bool sortInputElements(const std::unique_ptr &a, + const std::unique_ptr &b) { + return a->getOrdinal() < b->getOrdinal(); +} +} + +bool InputGraph::addInputElement(std::unique_ptr ie) { + _inputArgs.push_back(std::move(ie)); + return true; +} + +bool InputGraph::assignOrdinals() { + for (auto &ie : _inputArgs) + ie->setOrdinal(++_ordinal); + return true; +} + +void InputGraph::doPostProcess() { + std::stable_sort(_inputArgs.begin(), _inputArgs.end(), sortInputElements); +} + +bool InputGraph::validate() { + for (auto &ie : _inputArgs) + if (!ie->validate()) + return false; + return true; +} + +bool InputGraph::dump(raw_ostream &diagnostics) { + for (auto &ie : _inputArgs) + if (!ie->dump(diagnostics)) + return false; + return true; +} + +/// \brief Insert element at position +void InputGraph::insertElementsAt( + std::vector > inputElements, + Position position, size_t pos) { + if (position == InputGraph::Position::BEGIN) + pos = 0; + else if (position == InputGraph::Position::END) + pos = _inputArgs.size(); + _inputArgs.insert(_inputArgs.begin() + pos, + std::make_move_iterator(inputElements.begin()), + std::make_move_iterator(inputElements.end())); +} + +void InputGraph::insertOneElementAt(std::unique_ptr element, + Position position, size_t pos) { + if (position == InputGraph::Position::BEGIN) + pos = 0; + else if (position == InputGraph::Position::END) + pos = _inputArgs.size(); + _inputArgs.insert(_inputArgs.begin() + pos, std::move(element)); +} + +/// \brief Helper functions for the resolver +ErrorOr InputGraph::getNextInputElement() { + if (_nextElementIndex >= _inputArgs.size()) + return make_error_code(InputGraphError::no_more_elements); + return _inputArgs[_nextElementIndex++].get(); +} + +/// \brief Set the index on what inputElement has to be returned +error_code InputGraph::setNextElementIndex(uint32_t index) { + if (index > _inputArgs.size()) + return make_error_code(llvm::errc::invalid_argument); + _nextElementIndex = index; + return error_code::success(); +} + +/// InputElement + +/// \brief Initialize the Input Element, The ordinal value of an input Element +/// is initially set to -1, if the user wants to override its ordinal, +/// let the user do it +InputElement::InputElement(Kind type, int64_t ordinal) + : _kind(type), _ordinal(ordinal), _weight(0) {} + +/// FileNode +FileNode::FileNode(StringRef path, int64_t ordinal) + : InputElement(InputElement::Kind::File, ordinal), _path(path), + _resolveState(Resolver::StateNoChange), _nextFileIndex(0) {} + +/// \brief Read the file into _buffer. +error_code FileNode::getBuffer(StringRef filePath) { + // Create a memory buffer + OwningPtr opmb; + + if (error_code ec = MemoryBuffer::getFileOrSTDIN(filePath, opmb)) + return ec; + + std::unique_ptr mb(opmb.take()); + _buffer = std::move(mb); + + return error_code::success(); +} + +// Reset the next file that would be be processed by the resolver. +// Reset the resolve state too. +void FileNode::resetNextIndex() { + _nextFileIndex = 0; + setResolveState(Resolver::StateNoChange); +} + +/// ControlNode + +/// \brief Get the resolver State. The return value of the resolve +/// state for a control node is the or'ed value of the resolve states +/// contained in it. +uint32_t ControlNode::getResolveState() const { + uint32_t resolveState = Resolver::StateNoChange; + for (auto &elem : _elements) + resolveState |= elem->getResolveState(); + return resolveState; +} + +/// \brief Set the resolve state for the current element +/// thats processed by the resolver. +void ControlNode::setResolveState(uint32_t resolveState) { + if (_elements.empty()) + return; + _elements[_currentElementIndex]->setResolveState(resolveState); +} + +/// SimpleFileNode + +SimpleFileNode::SimpleFileNode(StringRef path, int64_t ordinal) + : InputElement(InputElement::Kind::SimpleFile, ordinal), _path(path), + _nextFileIndex(0), _resolveState(Resolver::StateNoChange) {} + +/// Group + +/// \brief Return the next file that need to be processed by the resolver. +/// This also processes input elements depending on the resolve status +/// of the input elements contained in the group. +ErrorOr Group::getNextFile() { + // If there are no elements, move on to the next input element + if (_elements.empty()) + return make_error_code(InputGraphError::no_more_files); + + for (;;) { + // If we have processed all the elements as part of this node + // check the resolver status for each input element and if the status + // has not changed, move onto the next file. + if (_nextElementIndex == _elements.size()) { + if (getResolveState() == Resolver::StateNoChange) + return make_error_code(InputGraphError::no_more_files); + resetNextIndex(); + } + _currentElementIndex = _nextElementIndex; + auto file = _elements[_nextElementIndex]->getNextFile(); + // Move on to the next element if we have finished processing all + // the files in the input element + if (error_code(file) == InputGraphError::no_more_files) { + _nextElementIndex++; + continue; + } + return *file; + } +} diff --git a/external/bsd/llvm/dist/lld/lib/Core/LinkingContext.cpp b/external/bsd/llvm/dist/lld/lib/Core/LinkingContext.cpp new file mode 100644 index 000000000..873d1d61c --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/LinkingContext.cpp @@ -0,0 +1,113 @@ +//===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/LinkingContext.h" +#include "lld/Core/Resolver.h" +#include "lld/ReaderWriter/Writer.h" +#include "lld/ReaderWriter/Simple.h" + +#include "llvm/ADT/Triple.h" + +namespace lld { + +LinkingContext::LinkingContext() + : _deadStrip(false), _globalsAreDeadStripRoots(false), + _searchArchivesToOverrideTentativeDefinitions(false), + _searchSharedLibrariesToOverrideTentativeDefinitions(false), + _warnIfCoalesableAtomsHaveDifferentCanBeNull(false), + _warnIfCoalesableAtomsHaveDifferentLoadName(false), + _printRemainingUndefines(true), _allowRemainingUndefines(false), + _logInputFiles(false), _allowShlibUndefines(false), + _outputFileType(OutputFileType::Default), _currentInputElement(nullptr), + _nextOrdinal(0) {} + +LinkingContext::~LinkingContext() {} + +bool LinkingContext::validate(raw_ostream &diagnostics) { + _yamlReader = createReaderYAML(*this); + _nativeReader = createReaderNative(*this); + return validateImpl(diagnostics); +} + +error_code LinkingContext::writeFile(const File &linkedFile) const { + return this->writer().writeFile(linkedFile, _outputPath); +} + +bool LinkingContext::createImplicitFiles( + std::vector > &result) const { + return this->writer().createImplicitFiles(result); +} + +std::unique_ptr LinkingContext::createEntrySymbolFile() const { + if (entrySymbolName().empty()) + return nullptr; + std::unique_ptr entryFile( + new SimpleFile(*this, "command line option -entry")); + entryFile->addAtom( + *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName()))); + return std::move(entryFile); +} + +std::unique_ptr LinkingContext::createUndefinedSymbolFile() const { + if (_initialUndefinedSymbols.empty()) + return nullptr; + std::unique_ptr undefinedSymFile( + new SimpleFile(*this, "command line option -u")); + for (auto undefSymStr : _initialUndefinedSymbols) + undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom( + *undefinedSymFile, undefSymStr))); + return std::move(undefinedSymFile); +} + +bool LinkingContext::createInternalFiles( + std::vector > &result) const { + std::unique_ptr internalFile; + internalFile = createEntrySymbolFile(); + if (internalFile) + result.push_back(std::move(internalFile)); + internalFile = createUndefinedSymbolFile(); + if (internalFile) + result.push_back(std::move(internalFile)); + return true; +} + +void LinkingContext::setResolverState(uint32_t state) { + _currentInputElement->setResolveState(state); +} + +ErrorOr LinkingContext::nextFile() { + // When nextFile() is called for the first time, _currentInputElement is not + // initialized. Initialize it with the first element of the input graph. + if (_currentInputElement == nullptr) { + ErrorOr elem = inputGraph().getNextInputElement(); + if (error_code(elem) == InputGraphError::no_more_elements) + return make_error_code(InputGraphError::no_more_files); + _currentInputElement = *elem; + } + + // Otherwise, try to get the next file of _currentInputElement. If the current + // input element points to an archive file, and there's a file left in the + // archive, it will succeed. If not, try to get the next file in the input + // graph. + for (;;) { + ErrorOr nextFile = _currentInputElement->getNextFile(); + if (error_code(nextFile) != InputGraphError::no_more_files) + return std::move(nextFile); + + ErrorOr elem = inputGraph().getNextInputElement(); + if (error_code(elem) == InputGraphError::no_more_elements || + *elem == nullptr) + return make_error_code(InputGraphError::no_more_files); + _currentInputElement = *elem; + } +} + +void LinkingContext::addPasses(PassManager &pm) {} + +} // end namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Core/PassManager.cpp b/external/bsd/llvm/dist/lld/lib/Core/PassManager.cpp new file mode 100644 index 000000000..749a8947e --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/PassManager.cpp @@ -0,0 +1,24 @@ +//===- lib/Core/PassManager.cpp - Manage linker passes --------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/PassManager.h" + +#include "lld/Core/Instrumentation.h" +#include "lld/Core/Pass.h" + +#include "llvm/Support/ErrorOr.h" + +namespace lld { +error_code PassManager::runOnFile(std::unique_ptr &mf) { + for (auto &pass : _passes) { + pass->perform(mf); + } + return error_code::success(); +} +} // end namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Core/Resolver.cpp b/external/bsd/llvm/dist/lld/lib/Core/Resolver.cpp new file mode 100644 index 000000000..5d9db38be --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/Resolver.cpp @@ -0,0 +1,493 @@ +//===- Core/Resolver.cpp - Resolves Atom References -----------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/Atom.h" +#include "lld/Core/ArchiveLibraryFile.h" +#include "lld/Core/File.h" +#include "lld/Core/SharedLibraryFile.h" +#include "lld/Core/Instrumentation.h" +#include "lld/Core/LLVM.h" +#include "lld/Core/Resolver.h" +#include "lld/Core/SymbolTable.h" +#include "lld/Core/LinkingContext.h" +#include "lld/Core/UndefinedAtom.h" + +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include + +namespace lld { + +namespace { + +/// This is used as a filter function to std::remove_if to dead strip atoms. +class NotLive { +public: + explicit NotLive(const llvm::DenseSet& la) : _liveAtoms(la) { } + + bool operator()(const Atom *atom) const { + // don't remove if live + if ( _liveAtoms.count(atom) ) + return false; + // don't remove if marked never-dead-strip + if (const DefinedAtom* defAtom = dyn_cast(atom)) { + if ( defAtom->deadStrip() == DefinedAtom::deadStripNever ) + return false; + } + // do remove this atom + return true; + } + +private: + const llvm::DenseSet _liveAtoms; +}; + + +/// This is used as a filter function to std::remove_if to coalesced atoms. +class AtomCoalescedAway { +public: + explicit AtomCoalescedAway(SymbolTable &sym) : _symbolTable(sym) {} + + bool operator()(const Atom *atom) const { + const Atom *rep = _symbolTable.replacement(atom); + return rep != atom; + } + +private: + SymbolTable &_symbolTable; +}; + +} // namespace + +// called before the first atom in any file is added with doAtom() +void Resolver::doFile(const File &file) {} + +void Resolver::handleFile(const File &file) { + uint32_t resolverState = Resolver::StateNoChange; + doFile(file); + for (const DefinedAtom *atom : file.defined()) { + doDefinedAtom(*atom); + resolverState |= StateNewDefinedAtoms; + } + for (const UndefinedAtom *undefAtom : file.undefined()) { + doUndefinedAtom(*undefAtom); + resolverState |= StateNewUndefinedAtoms; + } + for (const SharedLibraryAtom *shlibAtom : file.sharedLibrary()) { + doSharedLibraryAtom(*shlibAtom); + resolverState |= StateNewSharedLibraryAtoms; + } + for (const AbsoluteAtom *absAtom : file.absolute()) { + doAbsoluteAtom(*absAtom); + resolverState |= StateNewAbsoluteAtoms; + } + _context.setResolverState(resolverState); +} + +void +Resolver::forEachUndefines(UndefCallback callback, bool searchForOverrides) { + // Handle normal archives + int64_t undefineGenCount = 0; + do { + undefineGenCount = _symbolTable.size(); + std::vector undefines; + _symbolTable.undefines(undefines); + for (const UndefinedAtom *undefAtom : undefines) { + StringRef undefName = undefAtom->name(); + // load for previous undefine may also have loaded this undefine + if (!_symbolTable.isDefined(undefName)) + callback(undefName, false); + // If the undefined symbol has an alternative name, try to resolve the + // symbol with the name to give it a second chance. This feature is used + // for COFF "weak external" symbol. + if (!_symbolTable.isDefined(undefName)) { + if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) { + _symbolTable.addReplacement(undefAtom, fallbackUndefAtom); + _symbolTable.add(*fallbackUndefAtom); + } + } + } + // search libraries for overrides of common symbols + if (searchForOverrides) { + std::vector tentDefNames; + _symbolTable.tentativeDefinitions(tentDefNames); + for (StringRef tentDefName : tentDefNames) { + // Load for previous tentative may also have loaded + // something that overrode this tentative, so always check. + const Atom *curAtom = _symbolTable.findByName(tentDefName); + assert(curAtom != nullptr); + if (const DefinedAtom *curDefAtom = dyn_cast(curAtom)) { + if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) + callback(tentDefName, true); + } + } + } + } while (undefineGenCount != _symbolTable.size()); +} + +void Resolver::handleArchiveFile(const File &file) { + const ArchiveLibraryFile *archiveFile = dyn_cast(&file); + auto callback = [&](StringRef undefName, bool dataSymbolOnly) { + if (const File *member = archiveFile->find(undefName, dataSymbolOnly)) { + member->setOrdinal(_context.getNextOrdinalAndIncrement()); + handleFile(*member); + } + }; + bool searchForOverrides = _context.searchArchivesToOverrideTentativeDefinitions(); + forEachUndefines(callback, searchForOverrides); +} + +void Resolver::handleSharedLibrary(const File &file) { + // Add all the atoms from the shared library + const SharedLibraryFile *sharedLibrary = dyn_cast(&file); + handleFile(*sharedLibrary); + + auto callback = [&](StringRef undefName, bool dataSymbolOnly) { + if (const SharedLibraryAtom *shAtom = sharedLibrary->exports( + undefName, dataSymbolOnly)) + doSharedLibraryAtom(*shAtom); + }; + bool searchForOverrides = + _context.searchSharedLibrariesToOverrideTentativeDefinitions(); + forEachUndefines(callback, searchForOverrides); +} + +void Resolver::doUndefinedAtom(const UndefinedAtom& atom) { + DEBUG_WITH_TYPE("resolver", llvm::dbgs() + << " UndefinedAtom: " + << llvm::format("0x%09lX", &atom) + << ", name=" + << atom.name() + << "\n"); + + // add to list of known atoms + _atoms.push_back(&atom); + + // tell symbol table + _symbolTable.add(atom); +} + + +// called on each atom when a file is added +void Resolver::doDefinedAtom(const DefinedAtom &atom) { + DEBUG_WITH_TYPE("resolver", llvm::dbgs() + << " DefinedAtom: " + << llvm::format("0x%09lX", &atom) + << ", file=#" + << atom.file().ordinal() + << ", atom=#" + << atom.ordinal() + << ", name=" + << atom.name() + << "\n"); + + // Verify on zero-size atoms are pinned to start or end of section. + switch ( atom.sectionPosition() ) { + case DefinedAtom::sectionPositionStart: + case DefinedAtom::sectionPositionEnd: + assert(atom.size() == 0); + break; + case DefinedAtom::sectionPositionEarly: + case DefinedAtom::sectionPositionAny: + break; + } + + // add to list of known atoms + _atoms.push_back(&atom); + + // tell symbol table + _symbolTable.add(atom); + + if (_context.deadStrip()) { + // add to set of dead-strip-roots, all symbols that + // the compiler marks as don't strip + if (atom.deadStrip() == DefinedAtom::deadStripNever) + _deadStripRoots.insert(&atom); + } +} + +void Resolver::doSharedLibraryAtom(const SharedLibraryAtom& atom) { + DEBUG_WITH_TYPE("resolver", llvm::dbgs() + << " SharedLibraryAtom: " + << llvm::format("0x%09lX", &atom) + << ", name=" + << atom.name() + << "\n"); + + // add to list of known atoms + _atoms.push_back(&atom); + + // tell symbol table + _symbolTable.add(atom); +} + +void Resolver::doAbsoluteAtom(const AbsoluteAtom& atom) { + DEBUG_WITH_TYPE("resolver", llvm::dbgs() + << " AbsoluteAtom: " + << llvm::format("0x%09lX", &atom) + << ", name=" + << atom.name() + << "\n"); + + // add to list of known atoms + _atoms.push_back(&atom); + + // tell symbol table + if (atom.scope() != Atom::scopeTranslationUnit) { + _symbolTable.add(atom); + } +} + + + +// utility to add a vector of atoms +void Resolver::addAtoms(const std::vector& newAtoms) { + for (const DefinedAtom *newAtom : newAtoms) { + this->doDefinedAtom(*newAtom); + } +} + +// Keep adding atoms until _context.nextFile() returns an error. This function +// is where undefined atoms are resolved. +bool Resolver::resolveUndefines() { + ScopedTask task(getDefaultDomain(), "resolveUndefines"); + + for (;;) { + ErrorOr file = _context.nextFile(); + _context.setResolverState(Resolver::StateNoChange); + if (error_code(file) == InputGraphError::no_more_files) + return true; + if (!file) { + llvm::errs() << "Error occurred in nextFile: " + << error_code(file).message() << "\n"; + return false; + } + + switch (file->kind()) { + case File::kindObject: + assert(!file->hasOrdinal()); + file->setOrdinal(_context.getNextOrdinalAndIncrement()); + handleFile(*file); + break; + case File::kindArchiveLibrary: + if (!file->hasOrdinal()) + file->setOrdinal(_context.getNextOrdinalAndIncrement()); + handleArchiveFile(*file); + break; + case File::kindSharedLibrary: + if (!file->hasOrdinal()) + file->setOrdinal(_context.getNextOrdinalAndIncrement()); + handleSharedLibrary(*file); + break; + case File::kindLinkerScript: + llvm_unreachable("linker script should not be returned by nextFile()"); + } + } +} + +// switch all references to undefined or coalesced away atoms +// to the new defined atom +void Resolver::updateReferences() { + ScopedTask task(getDefaultDomain(), "updateReferences"); + for(const Atom *atom : _atoms) { + if (const DefinedAtom* defAtom = dyn_cast(atom)) { + for (const Reference *ref : *defAtom) { + const Atom* newTarget = _symbolTable.replacement(ref->target()); + (const_cast(ref))->setTarget(newTarget); + } + } + } +} + + +// for dead code stripping, recursively mark atoms "live" +void Resolver::markLive(const Atom &atom) { + // if already marked live, then done (stop recursion) + if ( _liveAtoms.count(&atom) ) + return; + + // mark this atom is live + _liveAtoms.insert(&atom); + + // mark all atoms it references as live + if ( const DefinedAtom* defAtom = dyn_cast(&atom)) { + for (const Reference *ref : *defAtom) { + const Atom *target = ref->target(); + if ( target != nullptr ) + this->markLive(*target); + } + } +} + + +// remove all atoms not actually used +void Resolver::deadStripOptimize() { + ScopedTask task(getDefaultDomain(), "deadStripOptimize"); + // only do this optimization with -dead_strip + if (!_context.deadStrip()) + return; + + // clear liveness on all atoms + _liveAtoms.clear(); + + // By default, shared libraries are built with all globals as dead strip roots + if (_context.globalsAreDeadStripRoots()) { + for (const Atom *atom : _atoms) { + const DefinedAtom *defAtom = dyn_cast(atom); + if (defAtom == nullptr) + continue; + if ( defAtom->scope() == DefinedAtom::scopeGlobal ) + _deadStripRoots.insert(defAtom); + } + } + + // Or, use list of names that are dead stip roots. + for (const StringRef &name : _context.deadStripRoots()) { + const Atom *symAtom = _symbolTable.findByName(name); + assert(symAtom); + if (symAtom->definition() == Atom::definitionUndefined) + // Dead-strip root atoms can be undefined at this point only when + // allowUndefines flag is on. Skip such undefines. + continue; + _deadStripRoots.insert(symAtom); + } + + // mark all roots as live, and recursively all atoms they reference + for ( const Atom *dsrAtom : _deadStripRoots) { + this->markLive(*dsrAtom); + } + + // now remove all non-live atoms from _atoms + _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), + NotLive(_liveAtoms)), _atoms.end()); +} + + +// error out if some undefines remain +bool Resolver::checkUndefines(bool final) { + // when using LTO, undefines are checked after bitcode is optimized + if (_haveLLVMObjs && !final) + return false; + + // build vector of remaining undefined symbols + std::vector undefinedAtoms; + _symbolTable.undefines(undefinedAtoms); + if (_context.deadStrip()) { + // When dead code stripping, we don't care if dead atoms are undefined. + undefinedAtoms.erase(std::remove_if( + undefinedAtoms.begin(), undefinedAtoms.end(), + NotLive(_liveAtoms)), undefinedAtoms.end()); + } + + // error message about missing symbols + if (!undefinedAtoms.empty()) { + // FIXME: need diagnostics interface for writing error messages + bool foundUndefines = false; + for (const UndefinedAtom *undefAtom : undefinedAtoms) { + const File &f = undefAtom->file(); + + // Skip over a weak symbol. + if (undefAtom->canBeNull() != UndefinedAtom::canBeNullNever) + continue; + + // If this is a library and undefined symbols are allowed on the + // target platform, skip over it. + if (isa(f) && _context.allowShlibUndefines()) + continue; + + // If the undefine is coalesced away, skip over it. + if (_symbolTable.replacement(undefAtom) != undefAtom) + continue; + + // Seems like this symbol is undefined. Warn that. + foundUndefines = true; + if (_context.printRemainingUndefines()) { + llvm::errs() << "Undefined Symbol: " << undefAtom->file().path() + << " : " << undefAtom->name() << "\n"; + } + } + if (foundUndefines) { + if (_context.printRemainingUndefines()) + llvm::errs() << "symbol(s) not found\n"; + return true; + } + } + return false; +} + + +// remove from _atoms all coaleseced away atoms +void Resolver::removeCoalescedAwayAtoms() { + ScopedTask task(getDefaultDomain(), "removeCoalescedAwayAtoms"); + _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), + AtomCoalescedAway(_symbolTable)), _atoms.end()); +} + +void Resolver::linkTimeOptimize() { + // FIX ME +} + +bool Resolver::resolve() { + if (!this->resolveUndefines()) + return false; + this->updateReferences(); + this->deadStripOptimize(); + if (this->checkUndefines(false)) { + if (!_context.allowRemainingUndefines()) + return false; + } + this->removeCoalescedAwayAtoms(); + this->linkTimeOptimize(); + this->_result->addAtoms(_atoms); + return true; +} + +void Resolver::MergedFile::addAtom(const Atom& atom) { + if (const DefinedAtom* defAtom = dyn_cast(&atom)) { + _definedAtoms._atoms.push_back(defAtom); + } else if (const UndefinedAtom* undefAtom = dyn_cast(&atom)) { + _undefinedAtoms._atoms.push_back(undefAtom); + } else if (const SharedLibraryAtom* slAtom = + dyn_cast(&atom)) { + _sharedLibraryAtoms._atoms.push_back(slAtom); + } else if (const AbsoluteAtom* abAtom = dyn_cast(&atom)) { + _absoluteAtoms._atoms.push_back(abAtom); + } else { + llvm_unreachable("atom has unknown definition kind"); + } +} + + +MutableFile::DefinedAtomRange Resolver::MergedFile::definedAtoms() { + return range::iterator>( + _definedAtoms._atoms.begin(), _definedAtoms._atoms.end()); +} + + + +void Resolver::MergedFile::addAtoms(std::vector& all) { + ScopedTask task(getDefaultDomain(), "addAtoms"); + DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n"); + for ( const Atom *atom : all ) { + DEBUG_WITH_TYPE("resolver", llvm::dbgs() + << llvm::format(" 0x%09lX", atom) + << ", name=" + << atom->name() + << "\n"); + this->addAtom(*atom); + } +} + + +} // namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Core/SymbolTable.cpp b/external/bsd/llvm/dist/lld/lib/Core/SymbolTable.cpp new file mode 100644 index 000000000..a8f5250de --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/SymbolTable.cpp @@ -0,0 +1,364 @@ +//===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/SymbolTable.h" +#include "lld/Core/AbsoluteAtom.h" +#include "lld/Core/Atom.h" +#include "lld/Core/DefinedAtom.h" +#include "lld/Core/File.h" +#include "lld/Core/LLVM.h" +#include "lld/Core/Resolver.h" +#include "lld/Core/SharedLibraryAtom.h" +#include "lld/Core/LinkingContext.h" +#include "lld/Core/UndefinedAtom.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include +#include + +namespace lld { +SymbolTable::SymbolTable(const LinkingContext &context) : _context(context) {} + +void SymbolTable::add(const UndefinedAtom &atom) { + this->addByName(atom); +} + +void SymbolTable::add(const SharedLibraryAtom &atom) { + this->addByName(atom); +} + +void SymbolTable::add(const AbsoluteAtom &atom) { + this->addByName(atom); +} + +void SymbolTable::add(const DefinedAtom &atom) { + if (!atom.name().empty() && + (atom.scope() != DefinedAtom::scopeTranslationUnit)) { + // Named atoms cannot be merged by content. + assert(atom.merge() != DefinedAtom::mergeByContent); + // Track named atoms that are not scoped to file (static). + this->addByName(atom); + } else if (atom.merge() == DefinedAtom::mergeByContent) { + // Named atoms cannot be merged by content. + assert(atom.name().empty()); + this->addByContent(atom); + } +} + +enum NameCollisionResolution { + NCR_First, + NCR_Second, + NCR_DupDef, + NCR_DupUndef, + NCR_DupShLib, + NCR_Error +}; + +static NameCollisionResolution cases[4][4] = { + //regular absolute undef sharedLib + { + // first is regular + NCR_DupDef, NCR_Error, NCR_First, NCR_First + }, + { + // first is absolute + NCR_Error, NCR_Error, NCR_First, NCR_First + }, + { + // first is undef + NCR_Second, NCR_Second, NCR_DupUndef, NCR_Second + }, + { + // first is sharedLib + NCR_Second, NCR_Second, NCR_First, NCR_DupShLib + } +}; + +static NameCollisionResolution collide(Atom::Definition first, + Atom::Definition second) { + return cases[first][second]; +} + +enum MergeResolution { + MCR_First, + MCR_Second, + MCR_Largest, + MCR_Error +}; + +static MergeResolution mergeCases[4][4] = { + // no tentative weak weakAddressUsed + { + // first is no + MCR_Error, MCR_First, MCR_First, MCR_First + }, + { + // first is tentative + MCR_Second, MCR_Largest, MCR_Second, MCR_Second + }, + { + // first is weak + MCR_Second, MCR_First, MCR_First, MCR_Second + }, + { + // first is weakAddressUsed + MCR_Second, MCR_First, MCR_First, MCR_First + } +}; + +static MergeResolution mergeSelect(DefinedAtom::Merge first, + DefinedAtom::Merge second) { + return mergeCases[first][second]; +} + +void SymbolTable::addByName(const Atom & newAtom) { + StringRef name = newAtom.name(); + assert(!name.empty()); + const Atom *existing = this->findByName(name); + if (existing == nullptr) { + // Name is not in symbol table yet, add it associate with this atom. + _nameTable[name] = &newAtom; + return; + } + + // Name is already in symbol table and associated with another atom. + bool useNew = true; + switch (collide(existing->definition(), newAtom.definition())) { + case NCR_First: + useNew = false; + break; + case NCR_Second: + useNew = true; + break; + case NCR_DupDef: + assert(existing->definition() == Atom::definitionRegular); + assert(newAtom.definition() == Atom::definitionRegular); + switch (mergeSelect(((DefinedAtom*)existing)->merge(), + ((DefinedAtom*)(&newAtom))->merge())) { + case MCR_First: + useNew = false; + break; + case MCR_Second: + useNew = true; + break; + case MCR_Largest: + useNew = true; + break; + case MCR_Error: + llvm::errs() << "Duplicate symbols: " + << existing->name() + << ":" + << existing->file().path() + << " and " + << newAtom.name() + << ":" + << newAtom.file().path() + << "\n"; + llvm::report_fatal_error("duplicate symbol error"); + break; + } + break; + case NCR_DupUndef: { + const UndefinedAtom* existingUndef = dyn_cast(existing); + const UndefinedAtom* newUndef = dyn_cast(&newAtom); + assert(existingUndef != nullptr); + assert(newUndef != nullptr); + + bool sameCanBeNull = (existingUndef->canBeNull() == newUndef->canBeNull()); + if (!sameCanBeNull && + _context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) { + llvm::errs() << "lld warning: undefined symbol " + << existingUndef->name() + << " has different weakness in " + << existingUndef->file().path() + << " and in " << newUndef->file().path() << "\n"; + } + + const UndefinedAtom *existingFallback = existingUndef->fallback(); + const UndefinedAtom *newFallback = newUndef->fallback(); + bool hasDifferentFallback = + (existingFallback && newFallback && + existingFallback->name() != newFallback->name()); + if (hasDifferentFallback) { + llvm::errs() << "lld warning: undefined symbol " + << existingUndef->name() << " has different fallback: " + << existingFallback->name() << " in " + << existingUndef->file().path() << " and " + << newFallback->name() << " in " + << newUndef->file().path() << "\n"; + } + + bool hasNewFallback = newUndef->fallback(); + if (sameCanBeNull) + useNew = hasNewFallback; + else + useNew = (newUndef->canBeNull() < existingUndef->canBeNull()); + break; + } + case NCR_DupShLib: { + const SharedLibraryAtom* curShLib = + dyn_cast(existing); + const SharedLibraryAtom* newShLib = + dyn_cast(&newAtom); + assert(curShLib != nullptr); + assert(newShLib != nullptr); + bool sameNullness = (curShLib->canBeNullAtRuntime() + == newShLib->canBeNullAtRuntime()); + bool sameName = curShLib->loadName().equals(newShLib->loadName()); + if (!sameName) { + useNew = false; + if (_context.warnIfCoalesableAtomsHaveDifferentLoadName()) { + // FIXME: need diagonstics interface for writing warning messages + llvm::errs() << "lld warning: shared library symbol " + << curShLib->name() + << " has different load path in " + << curShLib->file().path() + << " and in " + << newShLib->file().path(); + } + } else if (!sameNullness) { + useNew = false; + if (_context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) { + // FIXME: need diagonstics interface for writing warning messages + llvm::errs() << "lld warning: shared library symbol " + << curShLib->name() + << " has different weakness in " + << curShLib->file().path() + << " and in " + << newShLib->file().path(); + } + } else { + // Both shlib atoms are identical and can be coalesced. + useNew = false; + } + } + break; + case NCR_Error: + llvm::errs() << "SymbolTable: error while merging " << name << "\n"; + llvm::report_fatal_error("duplicate symbol error"); + break; + } + + if (useNew) { + // Update name table to use new atom. + _nameTable[name] = &newAtom; + // Add existing atom to replacement table. + _replacedAtoms[existing] = &newAtom; + } else { + // New atom is not being used. Add it to replacement table. + _replacedAtoms[&newAtom] = existing; + } +} + +unsigned SymbolTable::AtomMappingInfo::getHashValue(const DefinedAtom *atom) { + auto content = atom->rawContent(); + return llvm::hash_combine(atom->size(), + atom->contentType(), + llvm::hash_combine_range(content.begin(), + content.end())); +} + +bool SymbolTable::AtomMappingInfo::isEqual(const DefinedAtom * const l, + const DefinedAtom * const r) { + if (l == r) + return true; + if (l == getEmptyKey()) + return false; + if (r == getEmptyKey()) + return false; + if (l == getTombstoneKey()) + return false; + if (r == getTombstoneKey()) + return false; + + if (l->contentType() != r->contentType()) + return false; + if (l->size() != r->size()) + return false; + ArrayRef lc = l->rawContent(); + ArrayRef rc = r->rawContent(); + return memcmp(lc.data(), rc.data(), lc.size()) == 0; +} + +void SymbolTable::addByContent(const DefinedAtom & newAtom) { + // Currently only read-only constants can be merged. + assert(newAtom.permissions() == DefinedAtom::permR__); + AtomContentSet::iterator pos = _contentTable.find(&newAtom); + if (pos == _contentTable.end()) { + _contentTable.insert(&newAtom); + return; + } + const Atom* existing = *pos; + // New atom is not being used. Add it to replacement table. + _replacedAtoms[&newAtom] = existing; +} + +const Atom *SymbolTable::findByName(StringRef sym) { + NameToAtom::iterator pos = _nameTable.find(sym); + if (pos == _nameTable.end()) + return nullptr; + return pos->second; +} + +bool SymbolTable::isDefined(StringRef sym) { + const Atom *atom = this->findByName(sym); + if (atom == nullptr) + return false; + return atom->definition() != Atom::definitionUndefined; +} + +void SymbolTable::addReplacement(const Atom *replaced, + const Atom *replacement) { + _replacedAtoms[replaced] = replacement; +} + +const Atom *SymbolTable::replacement(const Atom *atom) { + AtomToAtom::iterator pos = _replacedAtoms.find(atom); + if (pos == _replacedAtoms.end()) + return atom; + // might be chain, recurse to end + return this->replacement(pos->second); +} + +unsigned int SymbolTable::size() { + return _nameTable.size(); +} + +void SymbolTable::undefines(std::vector &undefs) { + for (NameToAtom::iterator it = _nameTable.begin(), + end = _nameTable.end(); it != end; ++it) { + const Atom *atom = it->second; + assert(atom != nullptr); + if (const auto undef = dyn_cast(atom)) { + AtomToAtom::iterator pos = _replacedAtoms.find(undef); + if (pos != _replacedAtoms.end()) + continue; + undefs.push_back(undef); + } + } +} + +void SymbolTable::tentativeDefinitions(std::vector &names) { + for (auto entry : _nameTable) { + const Atom *atom = entry.second; + StringRef name = entry.first; + assert(atom != nullptr); + if (const DefinedAtom *defAtom = dyn_cast(atom)) + if (defAtom->merge() == DefinedAtom::mergeAsTentative) + names.push_back(name); + } +} +} // namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Core/TODO.txt b/external/bsd/llvm/dist/lld/lib/Core/TODO.txt new file mode 100644 index 000000000..196a3e02c --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Core/TODO.txt @@ -0,0 +1,18 @@ +lib/Core +~~~~~~~~ + +* Add endianness support to the native reader and writer. + +* The NativeReader has lots of similar code for converting arrays of ivar + data in mapped memory into arrays of objects. The commonality can be + factored out, maybe templatized. + +* The NativeFileFormat.h is old school C structs and constants. We scope + things better by defining constants used with a struct inside the struct + declaration. + +* The native reader and writer currently just blast in memory enumeration + values (e.g. DefinedAtom::Scope) into a byte in the disk format. To support + future changes to the enumerations, there should be a translation layer + to map disk values to in-memory values. + diff --git a/external/bsd/llvm/dist/lld/lib/Driver/CMakeLists.txt b/external/bsd/llvm/dist/lld/lib/Driver/CMakeLists.txt new file mode 100644 index 000000000..2006b2a92 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/CMakeLists.txt @@ -0,0 +1,36 @@ +set(LLVM_TARGET_DEFINITIONS UniversalDriverOptions.td) +tablegen(LLVM UniversalDriverOptions.inc -gen-opt-parser-defs) +set(LLVM_TARGET_DEFINITIONS GnuLdOptions.td) +tablegen(LLVM GnuLdOptions.inc -gen-opt-parser-defs) +set(LLVM_TARGET_DEFINITIONS CoreOptions.td) +tablegen(LLVM CoreOptions.inc -gen-opt-parser-defs) +set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td) +tablegen(LLVM DarwinLdOptions.inc -gen-opt-parser-defs) +set(LLVM_TARGET_DEFINITIONS WinLinkOptions.td) +tablegen(LLVM WinLinkOptions.inc -gen-opt-parser-defs) +add_public_tablegen_target(DriverOptionsTableGen) + +add_lld_library(lldDriver + CoreDriver.cpp + DarwinLdDriver.cpp + Driver.cpp + GnuLdDriver.cpp + WinLinkDriver.cpp + UniversalDriver.cpp + ) + +add_dependencies(lldDriver DriverOptionsTableGen) + +target_link_libraries(lldDriver + lldPasses + lldMachO + lldPECOFF + lldELF + lldCore + lldNative + lldReaderWriter + lldYAML + LLVMObject + LLVMOption + LLVMSupport + ) diff --git a/external/bsd/llvm/dist/lld/lib/Driver/CoreDriver.cpp b/external/bsd/llvm/dist/lld/lib/Driver/CoreDriver.cpp new file mode 100644 index 000000000..23ab17dba --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/CoreDriver.cpp @@ -0,0 +1,159 @@ +//===- lib/Driver/CoreDriver.cpp ------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Driver/Driver.h" +#include "lld/Driver/CoreInputGraph.h" +#include "lld/ReaderWriter/CoreLinkingContext.h" +#include "lld/ReaderWriter/Reader.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Option/Arg.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" + +using namespace lld; + +namespace { + +// Create enum with OPT_xxx values for each option in DarwinOptions.td +enum { + OPT_INVALID = 0, +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELP, META) \ + OPT_##ID, +#include "CoreOptions.inc" +#undef OPTION +}; + +// Create prefix string literals used in CoreOptions.td +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#include "CoreOptions.inc" +#undef PREFIX + +// Create table mapping all options defined in CoreOptions.td +static const llvm::opt::OptTable::Info infoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) \ + { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ + PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS }, +#include "CoreOptions.inc" +#undef OPTION +}; + +// Create OptTable class for parsing actual command line arguments +class CoreOptTable : public llvm::opt::OptTable { +public: + CoreOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){} +}; + +} // namespace anonymous + + +namespace lld { + +bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) { + CoreLinkingContext info; + if (!parse(argc, argv, info)) + return false; + return Driver::link(info); +} + +bool CoreDriver::parse(int argc, const char *argv[], CoreLinkingContext &ctx, + raw_ostream &diagnostics) { + // Parse command line options using CoreOptions.td + std::unique_ptr parsedArgs; + CoreOptTable table; + unsigned missingIndex; + unsigned missingCount; + parsedArgs.reset( + table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount)); + if (missingCount) { + diagnostics << "error: missing arg value for '" + << parsedArgs->getArgString(missingIndex) << "' expected " + << missingCount << " argument(s).\n"; + return false; + } + + std::unique_ptr inputGraph(new InputGraph()); + + // Set default options + ctx.setOutputPath("-"); + ctx.setDeadStripping(false); + ctx.setGlobalsAreDeadStripRoots(false); + ctx.setPrintRemainingUndefines(false); + ctx.setAllowRemainingUndefines(true); + ctx.setSearchArchivesToOverrideTentativeDefinitions(false); + + // Process all the arguments and create Input Elements + for (auto inputArg : *parsedArgs) { + switch (inputArg->getOption().getID()) { + case OPT_mllvm: + ctx.appendLLVMOption(inputArg->getValue()); + break; + + case OPT_entry: + ctx.setEntrySymbolName(inputArg->getValue()); + break; + + case OPT_output: + ctx.setOutputPath(inputArg->getValue()); + break; + + case OPT_dead_strip: + ctx.setDeadStripping(true); + break; + + case OPT_keep_globals: + ctx.setGlobalsAreDeadStripRoots(true); + break; + + case OPT_undefines_are_errors: + ctx.setPrintRemainingUndefines(true); + ctx.setAllowRemainingUndefines(false); + break; + + case OPT_commons_search_archives: + ctx.setSearchArchivesToOverrideTentativeDefinitions(true); + break; + + case OPT_add_pass: + ctx.addPassNamed(inputArg->getValue()); + break; + + case OPT_INPUT: + inputGraph->addInputElement(std::unique_ptr( + new COREFileNode(ctx, inputArg->getValue()))); + break; + + default: + break; + } + } + + if (!inputGraph->size()) { + diagnostics << "No input files\n"; + return false; + } + + ctx.setInputGraph(std::move(inputGraph)); + + // Validate the combination of options used. + return ctx.validate(diagnostics); +} + +} // namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Driver/CoreOptions.td b/external/bsd/llvm/dist/lld/lib/Driver/CoreOptions.td new file mode 100644 index 000000000..df7cb4173 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/CoreOptions.td @@ -0,0 +1,15 @@ +include "llvm/Option/OptParser.td" + +def output : Separate<["-"], "o">; +def entry : Separate<["-"], "e">; + +def dead_strip : Flag<["--"], "dead-strip">; +def undefines_are_errors : Flag<["--"], "undefines-are-errors">; +def keep_globals : Flag<["--"], "keep-globals">; +def commons_search_archives : Flag<["--"], "commons-search-archives">; + +def add_pass : Separate<["--"], "add-pass">; + +def target : Separate<["-"], "target">, HelpText<"Target triple to link for">; +def mllvm : Separate<["-"], "mllvm">, HelpText<"Options to pass to LLVM">; + diff --git a/external/bsd/llvm/dist/lld/lib/Driver/DarwinLdDriver.cpp b/external/bsd/llvm/dist/lld/lib/Driver/DarwinLdDriver.cpp new file mode 100644 index 000000000..c6c7c81ae --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/DarwinLdDriver.cpp @@ -0,0 +1,267 @@ +//===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Concrete instance of the Driver for darwin's ld. +/// +//===----------------------------------------------------------------------===// + +#include "lld/Driver/Driver.h" +#include "lld/Driver/DarwinInputGraph.h" +#include "lld/ReaderWriter/MachOLinkingContext.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Option/Arg.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/MachO.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" + + +namespace { + +// Create enum with OPT_xxx values for each option in DarwinLdOptions.td +enum { + OPT_INVALID = 0, +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELP, META) \ + OPT_##ID, +#include "DarwinLdOptions.inc" +#undef OPTION +}; + +// Create prefix string literals used in DarwinLdOptions.td +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#include "DarwinLdOptions.inc" +#undef PREFIX + +// Create table mapping all options defined in DarwinLdOptions.td +static const llvm::opt::OptTable::Info infoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) \ + { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ + PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS }, +#include "DarwinLdOptions.inc" +#undef OPTION +}; + +// Create OptTable class for parsing actual command line arguments +class DarwinLdOptTable : public llvm::opt::OptTable { +public: + DarwinLdOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){} +}; + + +} // namespace anonymous + +namespace lld { + +bool DarwinLdDriver::linkMachO(int argc, const char *argv[], + raw_ostream &diagnostics) { + MachOLinkingContext ctx; + if (!parse(argc, argv, ctx, diagnostics)) + return false; + if (ctx.doNothing()) + return true; + return link(ctx, diagnostics); +} + +bool DarwinLdDriver::parse(int argc, const char *argv[], + MachOLinkingContext &ctx, raw_ostream &diagnostics) { + // Parse command line options using DarwinLdOptions.td + std::unique_ptr parsedArgs; + DarwinLdOptTable table; + unsigned missingIndex; + unsigned missingCount; + bool globalWholeArchive = false; + parsedArgs.reset( + table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount)); + if (missingCount) { + diagnostics << "error: missing arg value for '" + << parsedArgs->getArgString(missingIndex) << "' expected " + << missingCount << " argument(s).\n"; + return false; + } + + for (auto it = parsedArgs->filtered_begin(OPT_UNKNOWN), + ie = parsedArgs->filtered_end(); it != ie; ++it) { + diagnostics << "warning: ignoring unknown argument: " + << (*it)->getAsString(*parsedArgs) << "\n"; + } + + // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static ) + if ( llvm::opt::Arg *kind = parsedArgs->getLastArg(OPT_dylib, OPT_relocatable, + OPT_bundle, OPT_static, OPT_preload)) { + switch (kind->getOption().getID()) { + case OPT_dylib: + ctx.setOutputFileType(llvm::MachO::MH_DYLIB); + ctx.setGlobalsAreDeadStripRoots(true); + break; + case OPT_relocatable: + ctx.setPrintRemainingUndefines(false); + ctx.setAllowRemainingUndefines(true); + ctx.setOutputFileType(llvm::MachO::MH_OBJECT); + break; + case OPT_bundle: + ctx.setOutputFileType(llvm::MachO::MH_BUNDLE); + break; + case OPT_static: + ctx.setOutputFileType(llvm::MachO::MH_EXECUTE); + break; + case OPT_preload: + ctx.setOutputFileType(llvm::MachO::MH_PRELOAD); + break; + } + } + + // Handle -e xxx + if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry)) + ctx.setEntrySymbolName(entry->getValue()); + + // Handle -o xxx + if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_output)) + ctx.setOutputPath(outpath->getValue()); + + // Handle -dead_strip + if (parsedArgs->getLastArg(OPT_dead_strip)) + ctx.setDeadStripping(true); + + // Handle -all_load + if (parsedArgs->getLastArg(OPT_all_load)) + globalWholeArchive = true; + + // Handle -install_name + if (llvm::opt::Arg *installName = parsedArgs->getLastArg(OPT_install_name)) + ctx.setInstallName(installName->getValue()); + + // Handle -mark_dead_strippable_dylib + if (parsedArgs->getLastArg(OPT_mark_dead_strippable_dylib)) + ctx.setDeadStrippableDylib(true); + + // Handle -compatibility_version and -current_version + if (llvm::opt::Arg *vers = + parsedArgs->getLastArg(OPT_compatibility_version)) { + if (ctx.outputFileType() != llvm::MachO::MH_DYLIB) { + diagnostics + << "error: -compatibility_version can only be used with -dylib\n"; + return false; + } + uint32_t parsedVers; + if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { + diagnostics << "error: -compatibility_version value is malformed\n"; + return false; + } + ctx.setCompatibilityVersion(parsedVers); + } + + if (llvm::opt::Arg *vers = parsedArgs->getLastArg(OPT_current_version)) { + if (ctx.outputFileType() != llvm::MachO::MH_DYLIB) { + diagnostics << "-current_version can only be used with -dylib\n"; + return false; + } + uint32_t parsedVers; + if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { + diagnostics << "error: -current_version value is malformed\n"; + return false; + } + ctx.setCurrentVersion(parsedVers); + } + + // Handle -bundle_loader + if (llvm::opt::Arg *loader = parsedArgs->getLastArg(OPT_bundle_loader)) + ctx.setBundleLoader(loader->getValue()); + + // Handle -arch xxx + if (llvm::opt::Arg *archStr = parsedArgs->getLastArg(OPT_arch)) { + ctx.setArch(MachOLinkingContext::archFromName(archStr->getValue())); + if (ctx.arch() == MachOLinkingContext::arch_unknown) { + diagnostics << "error: unknown arch named '" << archStr->getValue() + << "'\n"; + return false; + } + } + + // Handle -macosx_version_min or -ios_version_min + if (llvm::opt::Arg *minOS = parsedArgs->getLastArg( + OPT_macosx_version_min, + OPT_ios_version_min, + OPT_ios_simulator_version_min)) { + switch (minOS->getOption().getID()) { + case OPT_macosx_version_min: + if (ctx.setOS(MachOLinkingContext::OS::macOSX, minOS->getValue())) { + diagnostics << "error: malformed macosx_version_min value\n"; + return false; + } + break; + case OPT_ios_version_min: + if (ctx.setOS(MachOLinkingContext::OS::iOS, minOS->getValue())) { + diagnostics << "error: malformed ios_version_min value\n"; + return false; + } + break; + case OPT_ios_simulator_version_min: + if (ctx.setOS(MachOLinkingContext::OS::iOS_simulator, + minOS->getValue())) { + diagnostics << "error: malformed ios_simulator_version_min value\n"; + return false; + } + break; + } + } + else { + // No min-os version on command line, check environment variables + } + + // Handle -help + if (parsedArgs->getLastArg(OPT_help)) { + table.PrintHelp(llvm::outs(), argv[0], "LLVM Darwin Linker", false); + // If only -help on command line, don't try to do any linking + if (argc == 2) { + ctx.setDoNothing(true); + return true; + } + } + + // Handle -mllvm + for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_mllvm), + ie = parsedArgs->filtered_end(); + it != ie; ++it) { + ctx.appendLLVMOption((*it)->getValue()); + } + + std::unique_ptr inputGraph(new InputGraph()); + + // Handle input files + for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_INPUT), + ie = parsedArgs->filtered_end(); + it != ie; ++it) { + inputGraph->addInputElement(std::unique_ptr( + new MachOFileNode(ctx, (*it)->getValue(), globalWholeArchive))); + } + + if (!inputGraph->size()) { + diagnostics << "No input files\n"; + return false; + } + + ctx.setInputGraph(std::move(inputGraph)); + + // Validate the combination of options used. + return ctx.validate(diagnostics); +} + +} // namespace lld diff --git a/external/bsd/llvm/dist/lld/lib/Driver/DarwinLdOptions.td b/external/bsd/llvm/dist/lld/lib/Driver/DarwinLdOptions.td new file mode 100644 index 000000000..ff09d6a00 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/DarwinLdOptions.td @@ -0,0 +1,79 @@ +include "llvm/Option/OptParser.td" + + +// output kinds +def grp_kind : OptionGroup<"outs">, HelpText<"OUTPUT KIND">; +def relocatable : Flag<["-"], "r">, + HelpText<"Create relocatable object file">, Group; +def static : Flag<["-"], "static">, + HelpText<"Create static executable">, Group; +def dynamic : Flag<["-"], "dynamic">, + HelpText<"Create dynamic executable (default)">,Group; +def dylib : Flag<["-"], "dylib">, + HelpText<"Create dynamic library">, Group; +def bundle : Flag<["-"], "bundle">, + HelpText<"Create dynamic bundle">, Group; +def execute : Flag<["-"], "execute">, + HelpText<"Create main executable (default)">, Group; +def preload : Flag<["-"], "preload">, + HelpText<"Create preload">, Group; + +// optimizations +def grp_opts : OptionGroup<"opts">, HelpText<"OPTIMIZATIONS">; +def dead_strip : Flag<["-"], "dead_strip">, + HelpText<"Remove unreference code and data">, Group; +def macosx_version_min : Separate<["-"], "macosx_version_min">, + HelpText<"Minimum Mac OS X version">, Group; +def ios_version_min : Separate<["-"], "ios_version_min">, + HelpText<"Minimum iOS version">, Group; +def ios_simulator_version_min : Separate<["-"], "ios_simulator_version_min">, + HelpText<"Minimum iOS simulator version">, Group; +def mllvm : Separate<["-"], "mllvm">, + HelpText<"Options to pass to LLVM during LTO">, Group; + +// main executable options +def grp_main : OptionGroup<"opts">, HelpText<"MAIN EXECUTABLE OPTIONS">; +def entry : Separate<["-"], "e">, HelpText<"entry symbol name">,Group; + +// dylib executable options +def grp_dylib : OptionGroup<"opts">, HelpText<"DYLIB EXECUTABLE OPTIONS">; +def install_name : Separate<["-"], "install_name">, + HelpText<"The dylib's install name">, Group; +def mark_dead_strippable_dylib : Flag<["-"], "mark_dead_strippable_dylib">, + HelpText<"Marks the dylib as having no side effects during initialization">, + Group; +def compatibility_version : Separate<["-"], "compatibility_version">, + HelpText<"The dylib's compatibility version">, Group; +def current_version : Separate<["-"], "current_version">, + HelpText<"The dylib's current version">, Group; + +// dylib executable options - compatibility aliases +def dylib_install_name : Separate<["-"], "dylib_install_name">, + Alias; +def dylib_compatibility_version : + Separate<["-"], "dylib_compatibility_version">, + Alias; +def dylib_current_version : Separate<["-"], "dylib_current_version">, + Alias; + +// bundle executable options +def grp_bundle : OptionGroup<"opts">, HelpText<"BUNDLE EXECUTABLE OPTIONS">; +def bundle_loader : Separate<["-"], "bundle_loader">, + HelpText<"The executable that will be loading this Mach-O bundle">, + Group; + +// library options +def grp_libs : OptionGroup<"libs">, HelpText<"LIBRARY OPTIONS">; +def L : Joined<["-"], "L">, + HelpText<"Add directory to library search path">, Group; +def all_load : Flag<["-"], "all_load">, + HelpText<"Forces all members of all static libraries to be loaded">, + Group; + + +// general options +def output : Separate<["-"], "o">, HelpText<"Output file path">; +def arch : Separate<["-"], "arch">, HelpText<"Architecture to link">; + +// extras +def help : Flag<["-"], "help">; diff --git a/external/bsd/llvm/dist/lld/lib/Driver/Driver.cpp b/external/bsd/llvm/dist/lld/lib/Driver/Driver.cpp new file mode 100644 index 000000000..f4012279d --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/Driver.cpp @@ -0,0 +1,137 @@ +//===- lib/Driver/Driver.cpp - Linker Driver Emulator ---------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Driver/Driver.h" + +#include "lld/Core/LLVM.h" +#include "lld/Core/Instrumentation.h" +#include "lld/Core/PassManager.h" +#include "lld/Core/Parallel.h" +#include "lld/Core/Resolver.h" +#include "lld/ReaderWriter/Reader.h" +#include "lld/ReaderWriter/Writer.h" +#include "lld/Passes/RoundTripNativePass.h" +#include "lld/Passes/RoundTripYAMLPass.h" + +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Option/Arg.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" + +#include + +namespace lld { + +/// This is where the link is actually performed. +bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) { + // Honor -mllvm + if (!context.llvmOptions().empty()) { + unsigned numArgs = context.llvmOptions().size(); + const char **args = new const char *[numArgs + 2]; + args[0] = "lld (LLVM option parsing)"; + for (unsigned i = 0; i != numArgs; ++i) + args[i + 1] = context.llvmOptions()[i]; + args[numArgs + 1] = 0; + llvm::cl::ParseCommandLineOptions(numArgs + 1, args); + } + InputGraph &inputGraph = context.inputGraph(); + if (!inputGraph.size()) + return false; + + bool fail = false; + + // Read inputs + ScopedTask readTask(getDefaultDomain(), "Read Args"); + TaskGroup tg; + std::mutex diagnosticsMutex; + for (auto &ie : inputGraph.inputElements()) { + tg.spawn([&] { + // Writes to the same output stream is not guaranteed to be thread-safe. + // We buffer the diagnostics output to a separate string-backed output + // stream, acquire the lock, and then print it out. + std::string buf; + llvm::raw_string_ostream stream(buf); + + if (error_code ec = ie->parse(context, stream)) { + FileNode *fileNode = dyn_cast(ie.get()); + stream << fileNode->errStr(ec) << "\n"; + fail = true; + } + + stream.flush(); + if (!buf.empty()) { + std::lock_guard lock(diagnosticsMutex); + diagnostics << buf; + } + }); + } + tg.sync(); + readTask.end(); + + if (fail) + return false; + + std::unique_ptr fileNode( + new SimpleFileNode("Internal Files")); + + InputGraph::FileVectorT internalFiles; + context.createInternalFiles(internalFiles); + + if (internalFiles.size()) + fileNode->appendInputFiles(std::move(internalFiles)); + + // Give target a chance to add files. + InputGraph::FileVectorT implicitFiles; + context.createImplicitFiles(implicitFiles); + if (implicitFiles.size()) + fileNode->appendInputFiles(std::move(implicitFiles)); + + context.inputGraph().insertOneElementAt(std::move(fileNode), + InputGraph::Position::BEGIN); + + context.inputGraph().assignOrdinals(); + + context.inputGraph().doPostProcess(); + + // Do core linking. + ScopedTask resolveTask(getDefaultDomain(), "Resolve"); + Resolver resolver(context); + if (!resolver.resolve()) + return false; + std::unique_ptr merged = resolver.resultFile(); + resolveTask.end(); + + // Run passes on linked atoms. + ScopedTask passTask(getDefaultDomain(), "Passes"); + PassManager pm; + context.addPasses(pm); + +#ifndef NDEBUG + pm.add(std::unique_ptr(new RoundTripYAMLPass(context))); + pm.add(std::unique_ptr(new RoundTripNativePass(context))); +#endif + + pm.runOnFile(merged); + passTask.end(); + + // Give linked atoms to Writer to generate output file. + ScopedTask writeTask(getDefaultDomain(), "Write"); + if (error_code ec = context.writeFile(*merged)) { + diagnostics << "Failed to write file '" << context.outputPath() + << "': " << ec.message() << "\n"; + return false; + } + + return true; +} + +} // namespace diff --git a/external/bsd/llvm/dist/lld/lib/Driver/GnuLdDriver.cpp b/external/bsd/llvm/dist/lld/lib/Driver/GnuLdDriver.cpp new file mode 100644 index 000000000..c2c777785 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/GnuLdDriver.cpp @@ -0,0 +1,362 @@ +//===- lib/Driver/GnuLdDriver.cpp -----------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Concrete instance of the Driver for GNU's ld. +/// +//===----------------------------------------------------------------------===// + +#include "lld/Driver/Driver.h" +#include "lld/Driver/GnuLdInputGraph.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Option/Arg.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" + +using namespace lld; + +namespace { + +// Create enum with OPT_xxx values for each option in GnuLdOptions.td +enum { + OPT_INVALID = 0, +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELP, META) \ + OPT_##ID, +#include "GnuLdOptions.inc" +#undef OPTION +}; + +// Create prefix string literals used in GnuLdOptions.td +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#include "GnuLdOptions.inc" +#undef PREFIX + +// Create table mapping all options defined in GnuLdOptions.td +static const llvm::opt::OptTable::Info infoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) \ + { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ + PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS }, +#include "GnuLdOptions.inc" +#undef OPTION +}; + + +// Create OptTable class for parsing actual command line arguments +class GnuLdOptTable : public llvm::opt::OptTable { +public: + GnuLdOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){} +}; + +} // namespace + +llvm::ErrorOr ELFFileNode::getPath(const LinkingContext &) const { + if (!_isDashlPrefix) + return _path; + return _elfLinkingContext.searchLibrary(_path, _libraryPaths); +} + +std::string ELFFileNode::errStr(error_code errc) { + if (errc == llvm::errc::no_such_file_or_directory) { + if (_isDashlPrefix) + return (Twine("Unable to find library -l") + _path).str(); + return (Twine("Unable to find file ") + _path).str(); + } + return FileNode::errStr(errc); +} + +bool GnuLdDriver::linkELF(int argc, const char *argv[], + raw_ostream &diagnostics) { + std::unique_ptr options; + if (!parse(argc, argv, options, diagnostics)) + return false; + if (!options) + return true; + + return link(*options, diagnostics); +} + +bool GnuLdDriver::parse(int argc, const char *argv[], + std::unique_ptr &context, + raw_ostream &diagnostics) { + // Parse command line options using GnuLdOptions.td + std::unique_ptr parsedArgs; + GnuLdOptTable table; + unsigned missingIndex; + unsigned missingCount; + + parsedArgs.reset( + table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount)); + if (missingCount) { + diagnostics << "error: missing arg value for '" + << parsedArgs->getArgString(missingIndex) << "' expected " + << missingCount << " argument(s).\n"; + return false; + } + + // Handle --help + if (parsedArgs->getLastArg(OPT_help)) { + table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false); + return true; + } + + // Use -target or use default target triple to instantiate LinkingContext + llvm::Triple triple; + if (llvm::opt::Arg *trip = parsedArgs->getLastArg(OPT_target)) + triple = llvm::Triple(trip->getValue()); + else + triple = getDefaultTarget(argv[0]); + std::unique_ptr ctx(ELFLinkingContext::create(triple)); + + if (!ctx) { + diagnostics << "unknown target triple\n"; + return false; + } + + std::unique_ptr inputGraph(new InputGraph()); + std::stack controlNodeStack; + + // Positional options for an Input File + std::vector searchPath; + bool isWholeArchive = false; + bool asNeeded = false; + bool _outputOptionSet = false; + + // Create a dynamic executable by default + ctx->setOutputELFType(llvm::ELF::ET_EXEC); + ctx->setIsStaticExecutable(false); + ctx->setAllowShlibUndefines(false); + ctx->setUseShlibUndefines(true); + + int index = 0; + + // Process all the arguments and create Input Elements + for (auto inputArg : *parsedArgs) { + switch (inputArg->getOption().getID()) { + case OPT_mllvm: + ctx->appendLLVMOption(inputArg->getValue()); + break; + case OPT_relocatable: + ctx->setOutputELFType(llvm::ELF::ET_REL); + ctx->setPrintRemainingUndefines(false); + ctx->setAllowRemainingUndefines(true); + break; + case OPT_static: + ctx->setOutputELFType(llvm::ELF::ET_EXEC); + ctx->setIsStaticExecutable(true); + break; + case OPT_shared: + ctx->setOutputELFType(llvm::ELF::ET_DYN); + ctx->setAllowShlibUndefines(true); + ctx->setUseShlibUndefines(false); + break; + case OPT_e: + ctx->setEntrySymbolName(inputArg->getValue()); + break; + + case OPT_output: + _outputOptionSet = true; + ctx->setOutputPath(inputArg->getValue()); + break; + + case OPT_noinhibit_exec: + ctx->setAllowRemainingUndefines(true); + break; + + case OPT_merge_strings: + ctx->setMergeCommonStrings(true); + break; + + case OPT_t: + ctx->setLogInputFiles(true); + break; + + case OPT_no_allow_shlib_undefs: + ctx->setAllowShlibUndefines(false); + break; + + case OPT_allow_shlib_undefs: + ctx->setAllowShlibUndefines(true); + break; + + case OPT_use_shlib_undefs: + ctx->setUseShlibUndefines(true); + break; + + case OPT_dynamic_linker: + ctx->setInterpreter(inputArg->getValue()); + break; + + case OPT_nmagic: + ctx->setOutputMagic(ELFLinkingContext::OutputMagic::NMAGIC); + ctx->setIsStaticExecutable(true); + break; + + case OPT_omagic: + ctx->setOutputMagic(ELFLinkingContext::OutputMagic::OMAGIC); + ctx->setIsStaticExecutable(true); + break; + + case OPT_no_omagic: + ctx->setOutputMagic(ELFLinkingContext::OutputMagic::DEFAULT); + ctx->setNoAllowDynamicLibraries(); + break; + + case OPT_u: + ctx->addInitialUndefinedSymbol(inputArg->getValue()); + break; + + case OPT_init: + ctx->addInitFunction(inputArg->getValue()); + break; + + case OPT_fini: + ctx->addFiniFunction(inputArg->getValue()); + break; + + case OPT_output_filetype: + ctx->setOutputFileType(inputArg->getValue()); + break; + + case OPT_no_whole_archive: + isWholeArchive = false; + break; + case OPT_whole_archive: + isWholeArchive = true; + break; + case OPT_as_needed: + asNeeded = true; + break; + case OPT_no_as_needed: + asNeeded = false; + break; + case OPT_L: + searchPath.push_back(inputArg->getValue()); + break; + + case OPT_start_group: { + std::unique_ptr controlStart(new ELFGroup(*ctx, index++)); + controlNodeStack.push(controlStart.get()); + dyn_cast(controlNodeStack.top())->processControlEnter(); + inputGraph->addInputElement(std::move(controlStart)); + break; + } + + case OPT_end_group: + dyn_cast(controlNodeStack.top())->processControlExit(); + controlNodeStack.pop(); + break; + + case OPT_INPUT: + case OPT_l: { + std::unique_ptr inputFile(new ELFFileNode( + *ctx, inputArg->getValue(), searchPath, index++, isWholeArchive, + asNeeded, inputArg->getOption().getID() == OPT_l)); + if (controlNodeStack.empty()) + inputGraph->addInputElement(std::move(inputFile)); + else + dyn_cast(controlNodeStack.top()) + ->processInputElement(std::move(inputFile)); + break; + } + + case OPT_rpath: { + SmallVector rpaths; + StringRef(inputArg->getValue()).split(rpaths, ":"); + for (auto path : rpaths) + ctx->addRpath(path); + break; + } + + case OPT_rpath_link: { + SmallVector rpaths; + StringRef(inputArg->getValue()).split(rpaths, ":"); + for (auto path : rpaths) + ctx->addRpathLink(path); + break; + } + + case OPT_sysroot: + ctx->setSysroot(inputArg->getValue()); + break; + + case OPT_soname: + ctx->setSharedObjectName(inputArg->getValue()); + break; + + default: + break; + } // end switch on option ID + } // end for + + if (!inputGraph->size()) { + diagnostics << "No input files\n"; + return false; + } + + // Set default output file name if the output file was not + // specified. + if (!_outputOptionSet) { + switch (ctx->outputFileType()) { + case LinkingContext::OutputFileType::YAML: + ctx->setOutputPath("-"); + break; + case LinkingContext::OutputFileType::Native: + ctx->setOutputPath("a.native"); + break; + default: + ctx->setOutputPath("a.out"); + break; + } + } + + if (ctx->outputFileType() == LinkingContext::OutputFileType::YAML) + inputGraph->dump(diagnostics); + + // Validate the combination of options used. + if (!ctx->validate(diagnostics)) + return false; + + ctx->setInputGraph(std::move(inputGraph)); + + context.swap(ctx); + + return true; +} + +/// Get the default target triple based on either the program name +/// (e.g. "x86-ibm-linux-lld") or the primary target llvm was configured for. +llvm::Triple GnuLdDriver::getDefaultTarget(const char *progName) { + SmallVector components; + llvm::SplitString(llvm::sys::path::stem(progName), components, "-"); + // If has enough parts to be start with a triple. + if (components.size() >= 4) { + llvm::Triple triple(components[0], components[1], components[2], + components[3]); + // If first component looks like an arch. + if (triple.getArch() != llvm::Triple::UnknownArch) + return triple; + } + + // Fallback to use whatever default triple llvm was configured for. + return llvm::Triple(llvm::sys::getDefaultTargetTriple()); +} diff --git a/external/bsd/llvm/dist/lld/lib/Driver/GnuLdOptions.td b/external/bsd/llvm/dist/lld/lib/Driver/GnuLdOptions.td new file mode 100644 index 000000000..0e9e43da8 --- /dev/null +++ b/external/bsd/llvm/dist/lld/lib/Driver/GnuLdOptions.td @@ -0,0 +1,240 @@ +include "llvm/Option/OptParser.td" + +//===----------------------------------------------------------------------===// +/// Utility Functions +//===----------------------------------------------------------------------===// +// Single and multiple dash options combined +multiclass smDash { + // Option + def "" : Separate<["-"], opt1>, HelpText; + def opt1_eq : Separate<["-"], opt1#"=">, + Alias(opt1)>; + // Compatibility aliases + def opt2_dashdash : Separate<["--"], opt2>, + Alias(opt1)>; + def opt2_dashdash_eq : Separate<["--"], opt2#"=">, + Alias(opt1)>; +} + +// Support -